diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies new file mode 100644 index 0000000..e42a038 --- /dev/null +++ b/example/.flutter-plugins-dependencies @@ -0,0 +1 @@ +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"image_picker","path":"/Users/reni/Downloads/Programas/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker-0.4.12+1/","dependencies":[]},{"name":"path_provider","path":"/Users/reni/Downloads/Programas/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-0.4.1/","dependencies":[]}],"android":[{"name":"image_picker","path":"/Users/reni/Downloads/Programas/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker-0.4.12+1/","dependencies":[]},{"name":"path_provider","path":"/Users/reni/Downloads/Programas/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-0.4.1/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"image_picker","dependencies":[]},{"name":"path_provider","dependencies":[]}],"date_created":"2021-05-01 15:40:37.479609","version":"2.1.0-12.2.pre"} \ No newline at end of file diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh new file mode 100755 index 0000000..417d45f --- /dev/null +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=/Users/reni/Downloads/Programas/flutter" +export "FLUTTER_APPLICATION_PATH=/Users/reni/Downloads/Projetos/Flutter/libs/flutter_luban/example" +export "COCOAPODS_PARALLEL_CODE_SIGN=true" +export "FLUTTER_TARGET=lib/main.dart" +export "FLUTTER_BUILD_DIR=build" +export "SYMROOT=${SOURCE_ROOT}/../build/ios" +export "FLUTTER_BUILD_NAME=1.0.0" +export "FLUTTER_BUILD_NUMBER=1" +export "DART_OBFUSCATION=false" +export "TRACK_WIDGET_CREATION=false" +export "TREE_SHAKE_ICONS=false" +export "PACKAGE_CONFIG=.packages" diff --git a/lib/src/flutter_luban.dart b/lib/src/flutter_luban.dart index f55911d..b690260 100644 --- a/lib/src/flutter_luban.dart +++ b/lib/src/flutter_luban.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'dart:isolate'; import 'dart:math'; import 'dart:typed_data'; +import 'package:flutter/foundation.dart' as Foundation; import 'package:flutter/foundation.dart'; import 'package:image/image.dart'; @@ -10,8 +11,21 @@ import 'package:image/image.dart'; class Luban { Luban._(); - static Future compressImage(CompressObject object) async { - return compute(_lubanCompress, object); + static Future?> compressImage(CompressObject object) async { + if (Foundation.kIsWeb || (object.path == null || object.path!.isEmpty)) { + return compute(_lubanCompress, object); + } else { + List? bytes = await compute(_lubanCompress, object); + if (bytes == null) { + return null; + } + File file = File(object.path!); + if (!file.existsSync()) { + file.createSync(recursive: true); + } + file.writeAsBytesSync(bytes, flush: true); + return bytes; + } } static Future compressImageQueue(CompressObject object) async { @@ -23,7 +37,7 @@ class Luban { return answer.first; } - static Future> compressImageList( + static Future?>> compressImageList( List objects) async { return compute(_lubanCompressList, objects); } @@ -38,36 +52,21 @@ class Luban { }); } - static List _lubanCompressList(List objects) { - var results = []; + static List?> _lubanCompressList(List objects) { + List?> results = []; objects.forEach((_o) { results.add(_lubanCompress(_o)); }); - return results as List; - } - - static bool _parseType(String path, List suffix) { - bool _result = false; - for (int i = 0; i < suffix.length; i++) { - if (path.endsWith(suffix[i])) { - _result = true; - break; - } - } - return _result; + return results; } - static String? _lubanCompress(CompressObject object) { - Image image = decodeImage(object.imageFile!.readAsBytesSync())!; - var length = object.imageFile!.lengthSync(); - print(object.imageFile!.path); + static List? _lubanCompress(CompressObject object) { + Image image = decodeImage(object.bytes)!; + var length = object.bytes.lengthInBytes; bool isLandscape = false; - const List jpgSuffix = ["jpg", "jpeg", "JPG", "JPEG"]; - const List pngSuffix = ["png", "PNG"]; - bool isJpg = _parseType(object.imageFile!.path, jpgSuffix); - bool isPng = false; - if (!isJpg) isPng = _parseType(object.imageFile!.path, pngSuffix); + bool isJpg = + object.imageType == ImageType.JPEG || object.imageType == ImageType.JPG; double size; int fixelW = image.width; @@ -85,26 +84,13 @@ class Luban { } else { scale = fixelW / fixelH; } - var decodedImageFile; - if (isJpg) - decodedImageFile = new File( - object.path! + '/img_${DateTime.now().millisecondsSinceEpoch}.jpg'); - else if (isPng) - decodedImageFile = new File( - object.path! + '/img_${DateTime.now().millisecondsSinceEpoch}.png'); - else - throw Exception("flutter_luban don't support this image type"); - - if (decodedImageFile.existsSync()) { - decodedImageFile.deleteSync(); - } + List bytes; var imageSize = length / 1024; if (scale <= 1 && scale > 0.5625) { if (fixelH < 1664) { if (imageSize < 150) { - decodedImageFile - .writeAsBytesSync(encodeJpg(image, quality: object.quality)); - return decodedImageFile.path; + bytes = (encodeJpg(image, quality: object.quality)); + return bytes; } size = (fixelW * fixelH) / pow(1664, 2) * 150; size = size < 60 ? 60 : size; @@ -127,9 +113,8 @@ class Luban { } } else if (scale <= 0.5625 && scale >= 0.5) { if (fixelH < 1280 && imageSize < 200) { - decodedImageFile - .writeAsBytesSync(encodeJpg(image, quality: object.quality)); - return decodedImageFile.path; + bytes = encodeJpg(image, quality: object.quality); + return bytes; } int multiple = fixelH / 1280 == 0 ? 1 : fixelH ~/ 1280; thumbW = fixelW / multiple; @@ -144,9 +129,8 @@ class Luban { size = size < 100 ? 100 : size; } if (imageSize < size) { - decodedImageFile - .writeAsBytesSync(encodeJpg(image, quality: object.quality)); - return decodedImageFile.path; + bytes = encodeJpg(image, quality: object.quality); + return bytes; } Image smallerImage; if (isLandscape) { @@ -159,22 +143,17 @@ class Luban { height: object.autoRatio ? null : thumbH.toInt()); } - if (decodedImageFile.existsSync()) { - decodedImageFile.deleteSync(); - } if (object.mode == CompressMode.LARGE2SMALL) { - _large2SmallCompressImage( + bytes = _large2SmallCompressImage( image: smallerImage, - file: decodedImageFile, quality: object.quality, targetSize: size, step: object.step, isJpg: isJpg, ); } else if (object.mode == CompressMode.SMALL2LARGE) { - _small2LargeCompressImage( + bytes = _small2LargeCompressImage( image: smallerImage, - file: decodedImageFile, quality: object.step, targetSize: size, step: object.step, @@ -182,18 +161,16 @@ class Luban { ); } else { if (imageSize < 500) { - _large2SmallCompressImage( + bytes = _large2SmallCompressImage( image: smallerImage, - file: decodedImageFile, quality: object.quality, targetSize: size, step: object.step, isJpg: isJpg, ); } else { - _small2LargeCompressImage( + bytes = _small2LargeCompressImage( image: smallerImage, - file: decodedImageFile, quality: object.step, targetSize: size, step: object.step, @@ -201,12 +178,11 @@ class Luban { ); } } - return decodedImageFile.path; + return bytes; } - static _large2SmallCompressImage({ + static List _large2SmallCompressImage({ Image? image, - File? file, quality, targetSize, step, @@ -217,29 +193,25 @@ class Luban { var tempImageSize = Uint8List.fromList(im).lengthInBytes; if (tempImageSize / 1024 > targetSize && quality > step) { quality -= step; - _large2SmallCompressImage( + return _large2SmallCompressImage( image: image, - file: file, quality: quality, targetSize: targetSize, step: step, ); - return; } - file!.writeAsBytesSync(im); + return im; } else { - _compressPng( + return _compressPng( image: image!, - file: file, targetSize: targetSize, large2Small: true, ); } } - static _small2LargeCompressImage({ + static List _small2LargeCompressImage({ Image? image, - File? file, quality, targetSize, step, @@ -250,21 +222,18 @@ class Luban { var tempImageSize = Uint8List.fromList(im).lengthInBytes; if (tempImageSize / 1024 < targetSize && quality <= 100) { quality += step; - _small2LargeCompressImage( + return _small2LargeCompressImage( image: image, - file: file, quality: quality, targetSize: targetSize, step: step, isJpg: isJpg, ); - return; } - file!.writeAsBytesSync(im); + return im; } else { - _compressPng( + return _compressPng( image: image!, - file: file, targetSize: targetSize, large2Small: false, ); @@ -272,9 +241,8 @@ class Luban { } ///level 1~9 level++ -> image-- - static void _compressPng({ + static List _compressPng({ required Image image, - File? file, level, targetSize, required bool large2Small, @@ -286,22 +254,20 @@ class Luban { _level = level ?? 9; } List im = encodePng(image, level: _level); - if (_level > 9 || _level < 1) { + if (_level >= 9 || _level <= 1) { } else { var tempImageSize = Uint8List.fromList(im).lengthInBytes; if (tempImageSize / 1024 > targetSize) { - _compressPng( + return _compressPng( image: image, - file: file, targetSize: targetSize, level: large2Small ? _level + 1 : _level - 1, large2Small: large2Small, ); - return; + //return; } } - - file!.writeAsBytesSync(im); + return im; } } @@ -311,22 +277,25 @@ enum CompressMode { AUTO, } +enum ImageType { JPG, JPEG, PNG } + class CompressObject { - final File? imageFile; - final String? path; + final Uint8List bytes; + final ImageType? imageType; final CompressMode mode; final int quality; final int step; + final String? path; ///If you are not sure whether the image detail property is correct, set true, otherwise the compressed ratio may be incorrect final bool autoRatio; - CompressObject({ - this.imageFile, - this.path, - this.mode: CompressMode.AUTO, - this.quality: 80, - this.step: 6, - this.autoRatio = true, - }); + CompressObject( + {required this.bytes, + required this.imageType, + this.mode: CompressMode.AUTO, + this.quality: 80, + this.step: 6, + this.autoRatio = true, + this.path}); } diff --git a/pubspec.lock b/pubspec.lock index a3c18b9..0fd14ff 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,56 +7,70 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "14.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.39.1" + version: "0.41.2" archive: dependency: transitive description: name: archive url: "https://pub.dartlang.org" source: hosted - version: "2.0.10" + version: "3.1.2" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.5.2" + version: "1.6.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" + version: "2.5.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.2.0" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" + version: "1.15.0" convert: dependency: transitive description: @@ -70,229 +84,173 @@ packages: name: coverage url: "https://pub.dartlang.org" source: hosted - version: "0.13.3+1" + version: "0.15.2" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" - csslib: + version: "3.0.1" + file: dependency: transitive description: - name: csslib + name: file url: "https://pub.dartlang.org" source: hosted - version: "0.16.1" + version: "6.1.0" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" - front_end: - dependency: transitive - description: - name: front_end - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.29" glob: dependency: transitive description: name: glob url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" - html: - dependency: transitive - description: - name: html - url: "https://pub.dartlang.org" - source: hosted - version: "0.14.0+3" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" + version: "2.0.1" http_multi_server: dependency: transitive description: name: http_multi_server url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "3.0.1" http_parser: dependency: transitive description: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.3" + version: "4.0.0" image: dependency: "direct main" description: name: image url: "https://pub.dartlang.org" source: hosted - version: "2.1.9" + version: "3.0.2" io: dependency: transitive description: name: io url: "https://pub.dartlang.org" source: hosted - version: "0.3.3" + version: "1.0.0" js: dependency: transitive description: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.1+1" - kernel: - dependency: transitive - description: - name: kernel - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.29" + version: "0.6.3" logging: dependency: transitive description: name: logging url: "https://pub.dartlang.org" source: hosted - version: "0.11.3+2" + version: "1.0.1" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.3.0" mime: dependency: transitive description: name: mime url: "https://pub.dartlang.org" source: hosted - version: "0.9.6+3" - multi_server_socket: - dependency: transitive - description: - name: multi_server_socket - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - node_interop: - dependency: transitive - description: - name: node_interop - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - node_io: - dependency: transitive - description: - name: node_io - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1+2" + version: "1.0.0" node_preamble: dependency: transitive description: name: node_preamble url: "https://pub.dartlang.org" source: hosted - version: "1.4.8" + version: "1.4.13" package_config: dependency: transitive description: name: package_config url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" - package_resolver: - dependency: transitive - description: - name: package_resolver - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.10" + version: "1.9.3" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" + version: "1.8.0" pedantic: dependency: transitive description: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.8.0+1" + version: "1.11.0" petitparser: dependency: transitive description: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" + version: "4.1.0" pool: dependency: transitive description: name: pool url: "https://pub.dartlang.org" source: hosted - version: "1.4.0" + version: "1.5.0" pub_semver: dependency: transitive description: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "1.4.2" + version: "2.0.0" shelf: dependency: transitive description: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "0.7.5" + version: "1.1.1" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.0.1" shelf_static: dependency: transitive description: name: shelf_static url: "https://pub.dartlang.org" source: hosted - version: "0.2.8" + version: "0.2.9+2" shelf_web_socket: dependency: transitive description: name: shelf_web_socket url: "https://pub.dartlang.org" source: hosted - version: "0.2.3" + version: "0.2.4+1" sky_engine: dependency: transitive description: flutter @@ -304,118 +262,125 @@ packages: name: source_map_stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.1.5" + version: "2.1.0" source_maps: dependency: transitive description: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.8" + version: "0.10.10" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.8.1" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" test: dependency: "direct dev" description: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.9.4" + version: "1.16.5" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.11" + version: "0.2.19" test_core: dependency: transitive description: name: test_core url: "https://pub.dartlang.org" source: hosted - version: "0.2.15" + version: "0.3.15" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.0" vm_service: dependency: transitive description: name: vm_service url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "6.2.0" watcher: dependency: transitive description: name: watcher url: "https://pub.dartlang.org" source: hosted - version: "0.9.7+12" + version: "1.0.0" web_socket_channel: dependency: transitive description: name: web_socket_channel url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" xml: dependency: transitive description: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.5.0" + version: "5.1.0" yaml: dependency: transitive description: name: yaml url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "3.1.0" sdks: - dart: ">=2.4.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 51bb5b6..9900839 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: image: ^3.0.2 dev_dependencies: - test: ^1.16.8 + test: ^1.9.4 # For information on the generic Dart part of this file, see the # following page: https://www.dartlang.org/tools/pub/pubspec