From 7e742a185a1bba690f826aaa2b59f77401e8df55 Mon Sep 17 00:00:00 2001 From: niuhuan Date: Thu, 17 Mar 2022 17:52:51 +0800 Subject: [PATCH] upload avatar on desktop --- lib/screens/GamesScreen.dart | 4 +- lib/screens/components/DesktopCropper.dart | 71 +++++++++++++++++++++ lib/screens/components/UserProfileCard.dart | 30 +++++++++ pubspec.lock | 49 ++++++++++++++ pubspec.yaml | 3 + 5 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 lib/screens/components/DesktopCropper.dart diff --git a/lib/screens/GamesScreen.dart b/lib/screens/GamesScreen.dart index 2d91daa..80521c2 100644 --- a/lib/screens/GamesScreen.dart +++ b/lib/screens/GamesScreen.dart @@ -50,7 +50,7 @@ class _GamesScreenState extends State { gameCard = GameCard(element); } else { wraps.add(Wrap( - children: [GameCard(element), gameCard!], + children: [GameCard(element), gameCard], alignment: WrapAlignment.center, )); gameCard = null; @@ -58,7 +58,7 @@ class _GamesScreenState extends State { } if (gameCard != null) { wraps.add(Wrap( - children: [gameCard!], + children: [gameCard], alignment: WrapAlignment.center, )); } diff --git a/lib/screens/components/DesktopCropper.dart b/lib/screens/components/DesktopCropper.dart new file mode 100644 index 0000000..bdc162e --- /dev/null +++ b/lib/screens/components/DesktopCropper.dart @@ -0,0 +1,71 @@ +import 'dart:io'; +import 'dart:ui' as ui; +import 'package:image/image.dart' as image; +import 'package:crop_image/crop_image.dart'; +import 'package:flutter/material.dart'; + +class DesktopCropper extends StatefulWidget { + final String? title; + final double? aspectRatio; + final String file; + + const DesktopCropper({ + Key? key, + this.title, + this.aspectRatio, + required this.file, + }) : super(key: key); + + @override + State createState() => _DesktopCropperState(); +} + +class _DesktopCropperState extends State { + late final _controller = CropController( + aspectRatio: widget.aspectRatio, + ); + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title ?? "图片裁剪"), + actions: [ + IconButton(onPressed: _finish, icon: const Icon(Icons.done)), + ], + ), + body: Center( + child: Padding( + padding: const EdgeInsets.all(12.0), + child: CropImage( + controller: _controller, + image: Image.file(File(widget.file)), + ), + ), + ), + ); + } + + Future _finish() async { + var cropped = await _controller.croppedBitmap(); + var data = await cropped.toByteData(format: ui.ImageByteFormat.png); + if (data != null) { + var u8list = data.buffer.asUint8List(); + image.Image? baseSizeImage = image.decodePng(u8list); + if (baseSizeImage != null) { + if (cropped.width > 200) { + baseSizeImage = + image.copyResize(baseSizeImage, height: 200, width: 200); + } + var f = image.encodeJpg(baseSizeImage!); + Navigator.of(context).pop(f); + } + } + } +} diff --git a/lib/screens/components/UserProfileCard.dart b/lib/screens/components/UserProfileCard.dart index b7ceb45..a81f719 100644 --- a/lib/screens/components/UserProfileCard.dart +++ b/lib/screens/components/UserProfileCard.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'dart:io'; import 'dart:ui'; +import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:image_cropper/image_cropper.dart'; import 'package:image_picker/image_picker.dart'; @@ -12,6 +13,8 @@ import 'package:pikapika/screens/components/Avatar.dart'; import 'package:pikapika/screens/components/Images.dart'; import 'package:pikapika/screens/components/ItemBuilder.dart'; +import 'DesktopCropper.dart'; + const double _cardHeight = 180; // 用户信息卡 @@ -120,6 +123,10 @@ class _UserProfileCardState extends State { onTap: () async { if (Platform.isAndroid || Platform.isIOS) { await _updateAvatarPhone(); + } else if (Platform.isMacOS || + Platform.isWindows || + Platform.isLinux) { + await _updateAvatarDesktop(); } }, child: Avatar(profile.avatar, size: 65), @@ -202,6 +209,29 @@ class _UserProfileCardState extends State { } } + Future _updateAvatarDesktop() async { + FilePickerResult? result = await FilePicker.platform.pickFiles( + type: FileType.image, + allowMultiple: false, + ); + if (result != null) { + List? buff = await Navigator.of(context).push( + MaterialPageRoute(builder: (BuildContext context) { + return DesktopCropper( + file: result.files.first.path!, + aspectRatio: 1, + title: "裁剪头像", + ); + }), + ); + if (buff != null) { + var data = base64Encode(buff); + await method.updateAvatar(data); + _reload(); + } + } + } + void _reload() { setState(() { _future = _load(); diff --git a/pubspec.lock b/pubspec.lock index 2d7747d..b59b132 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -8,6 +8,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1+2" + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.2" async: dependency: transitive description: @@ -57,6 +64,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + crop_image: + dependency: "direct main" + description: + name: crop_image + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" cross_file: dependency: transitive description: @@ -64,6 +78,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.3.2" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" cupertino_icons: dependency: "direct main" description: @@ -85,6 +106,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + file_picker: + dependency: "direct main" + description: + name: file_picker + url: "https://pub.dartlang.org" + source: hosted + version: "4.5.1" filesystem_picker: dependency: "direct main" description: @@ -168,6 +203,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.0" + image: + dependency: "direct main" + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.3" image_cropper: dependency: "direct main" description: @@ -446,6 +488,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.1" xml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 378eebd..f14693d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,6 +45,9 @@ dependencies: modal_bottom_sheet: ^2.0.0 image_cropper: ^1.5.0 image_picker: ^0.8.4+9 + file_picker: ^4.5.1 + crop_image: ^1.0.2 + image: ^3.1.3 dev_dependencies: flutter_test: