diff --git a/app/lib/features/editor/widgets/image_picker_handler.dart b/app/lib/features/editor/widgets/image_picker_handler.dart new file mode 100644 index 0000000..2adebea --- /dev/null +++ b/app/lib/features/editor/widgets/image_picker_handler.dart @@ -0,0 +1,67 @@ +// 图片选择 + 压缩 + 缩略图生成工具类 +// +// 职责: +// - 从相机/相册选择图片 +// - 压缩到合理尺寸(≤1024px, 质量 85) +// - 生成缩略图(≤200px, 质量 70) + +import 'package:flutter_image_compress/flutter_image_compress.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:uuid/uuid.dart'; + +/// 图片选择 + 压缩 + 缩略图生成 +class ImagePickerHandler { + static const _uuid = Uuid(); + + /// 从相机或相册选择图片 + /// 返回压缩后的本地文件路径,取消返回 null + static Future pickImage({required bool fromCamera}) async { + final picker = ImagePicker(); + final xFile = await picker.pickImage( + source: fromCamera ? ImageSource.camera : ImageSource.gallery, + maxWidth: 1024, + maxHeight: 1024, + imageQuality: 85, + ); + if (xFile == null) return null; + + // 压缩图片 + final compressedPath = await _compressImage(xFile.path); + return compressedPath; + } + + /// 生成缩略图路径 + static Future generateThumbnail(String imagePath) async { + final dir = await getApplicationDocumentsDirectory(); + final thumbName = 'thumb_${_uuid.v4()}.jpg'; + final thumbPath = '${dir.path}/$thumbName'; + + final result = await FlutterImageCompress.compressAndGetFile( + imagePath, + thumbPath, + minHeight: 200, + minWidth: 200, + quality: 70, + ); + + return result?.path ?? imagePath; + } + + /// 压缩原图 + static Future _compressImage(String path) async { + final dir = await getApplicationDocumentsDirectory(); + final fileName = 'img_${_uuid.v4()}.jpg'; + final targetPath = '${dir.path}/$fileName'; + + final result = await FlutterImageCompress.compressAndGetFile( + path, + targetPath, + quality: 85, + minWidth: 1024, + minHeight: 1024, + ); + + return result?.path ?? path; + } +}