import 'dart:io'; import 'dart:math'; import 'package:file_picker/file_picker.dart'; import 'package:image/image.dart'; import 'package:image_picker/image_picker.dart'; import 'package:logging/logging.dart'; import 'package:result_monad/result_monad.dart'; import '../globals.dart'; import '../models/exec_error.dart'; import '../models/media_attachment_uploads/image_types_enum.dart'; import '../models/media_attachment_uploads/media_upload_attachment.dart'; class MediaUploadAttachmentHelper { static final _logger = Logger('$MediaUploadAttachmentHelper'); static FutureResult, ExecError> getNewImagesFromCamera() async { final file = await ImagePicker().pickImage(source: ImageSource.camera); if (file != null) { return Result.ok([MediaUploadAttachment.newItem(file.path)]); } { return Result.ok([]); } } static FutureResult, ExecError> getImagesFromGallery() async { final files = []; if (useImagePicker) { final picker = ImagePicker(); final selectedFiles = await picker.pickMultiImage(); files.addAll(selectedFiles); } else { await _desktopImagesFromDisk().match( onSuccess: (selectedFiles) => files.addAll(selectedFiles), onError: (error) => _logger.severe(error), ); } return Result.ok( files.map((f) => MediaUploadAttachment.newItem(f.path)).toList()); } static FutureResult, dynamic> _desktopImagesFromDisk() async { final result = await FilePicker.platform.pickFiles( type: FileType.image, allowMultiple: true, ); if (result == null) { return Result.ok([]); } final files = result.files.map((f) => XFile(f.path!)).toList(); return Result.ok(files); } static Result, dynamic> getUploadableImageBytes(String path, {int maxSizeBytes = 800000}) { return runCatching(() { final file = File(path); final fileBytes = file.readAsBytesSync(); var size = file.statSync().size; if (size <= maxSizeBytes) { return Result.ok(fileBytes); } final imageType = ImageTypes.fromExtension(path); var scale = maxSizeBytes / size; late final Image original; switch (imageType) { case ImageTypes.gif: original = decodeGif(fileBytes)!; break; case ImageTypes.png: original = decodePng(fileBytes)!; break; case ImageTypes.jpg: original = decodeJpg(fileBytes)!; break; } late List resizedBytes; while (size > maxSizeBytes) { final newWidth = (original.width * sqrt(scale)).toInt(); final resized = copyResize(original, width: (newWidth).toInt()); switch (imageType) { case ImageTypes.gif: resizedBytes = encodeGif(resized); break; case ImageTypes.png: resizedBytes = encodePng(resized); break; case ImageTypes.jpg: resizedBytes = encodeJpg(resized, quality: 80); break; } size = resizedBytes.length; scale /= 2; } return Result.ok(resizedBytes); }); } }