diff --git a/packages/image_picker/CHANGELOG.md b/packages/image_picker/CHANGELOG.md index bd55c5f3deeb..a8e371c48072 100644 --- a/packages/image_picker/CHANGELOG.md +++ b/packages/image_picker/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.6.1 + +* New feature : Get images with custom quality. While picking images, user can pass `imageQuality` +parameter to compress image. + ## 0.6.0+20 * Android: Migrated information cache methods to use instance methods. diff --git a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerCache.java b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerCache.java index c189b35a5491..6e5121f10200 100644 --- a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerCache.java +++ b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerCache.java @@ -17,6 +17,7 @@ class ImagePickerCache { static final String MAP_KEY_PATH = "path"; static final String MAP_KEY_MAX_WIDTH = "maxWidth"; static final String MAP_KEY_MAX_HEIGHT = "maxHeight"; + static final String MAP_KEY_IMAGE_QUALITY = "imageQuality"; private static final String MAP_KEY_TYPE = "type"; private static final String MAP_KEY_ERROR_CODE = "errorCode"; private static final String MAP_KEY_ERROR_MESSAGE = "errorMessage"; @@ -28,6 +29,8 @@ class ImagePickerCache { "flutter_image_picker_error_message"; private static final String SHARED_PREFERENCE_MAX_WIDTH_KEY = "flutter_image_picker_max_width"; private static final String SHARED_PREFERENCE_MAX_HEIGHT_KEY = "flutter_image_picker_max_height"; + private static final String SHARED_PREFERENCE_IMAGE_QUALITY_KEY = + "flutter_image_picker_image_quality"; private static final String SHARED_PREFERENCE_TYPE_KEY = "flutter_image_picker_type"; private static final String SHARED_PREFERENCE_PENDING_IMAGE_URI_PATH_KEY = "flutter_image_picker_pending_image_uri"; @@ -55,11 +58,15 @@ private void setType(String type) { void saveDimensionWithMethodCall(MethodCall methodCall) { Double maxWidth = methodCall.argument(MAP_KEY_MAX_WIDTH); Double maxHeight = methodCall.argument(MAP_KEY_MAX_HEIGHT); - setMaxDimension(maxWidth, maxHeight); - } + int imageQuality = + methodCall.argument(MAP_KEY_IMAGE_QUALITY) == null + ? 100 + : (int) methodCall.argument(MAP_KEY_IMAGE_QUALITY); - private void setMaxDimension(Double maxWidth, Double maxHeight) { + setMaxDimension(maxWidth, maxHeight, imageQuality); + } + private void setMaxDimension(Double maxWidth, Double maxHeight, int imageQuality) { SharedPreferences.Editor editor = prefs.edit(); if (maxWidth != null) { editor.putLong(SHARED_PREFERENCE_MAX_WIDTH_KEY, Double.doubleToRawLongBits(maxWidth)); @@ -67,6 +74,11 @@ private void setMaxDimension(Double maxWidth, Double maxHeight) { if (maxHeight != null) { editor.putLong(SHARED_PREFERENCE_MAX_HEIGHT_KEY, Double.doubleToRawLongBits(maxHeight)); } + if (imageQuality > -1 && imageQuality < 101) { + editor.putInt(SHARED_PREFERENCE_IMAGE_QUALITY_KEY, imageQuality); + } else { + editor.putInt(SHARED_PREFERENCE_IMAGE_QUALITY_KEY, 100); + } editor.apply(); } @@ -130,8 +142,14 @@ Map getCacheMap() { resultMap.put(MAP_KEY_MAX_WIDTH, Double.longBitsToDouble(maxWidthValue)); } if (prefs.contains(SHARED_PREFERENCE_MAX_HEIGHT_KEY)) { - final long maxHeighValue = prefs.getLong(SHARED_PREFERENCE_MAX_HEIGHT_KEY, 0); - resultMap.put(MAP_KEY_MAX_HEIGHT, Double.longBitsToDouble(maxHeighValue)); + final long maxHeightValue = prefs.getLong(SHARED_PREFERENCE_MAX_HEIGHT_KEY, 0); + resultMap.put(MAP_KEY_MAX_HEIGHT, Double.longBitsToDouble(maxHeightValue)); + } + if (prefs.contains(SHARED_PREFERENCE_IMAGE_QUALITY_KEY)) { + final int imageQuality = prefs.getInt(SHARED_PREFERENCE_IMAGE_QUALITY_KEY, 100); + resultMap.put(MAP_KEY_MAX_HEIGHT, imageQuality); + } else { + resultMap.put(MAP_KEY_MAX_HEIGHT, 100); } } diff --git a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java index 2507904bf87d..a568eca4dc22 100644 --- a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java +++ b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java @@ -217,7 +217,12 @@ void retrieveLostImage(MethodChannel.Result result) { if (path != null) { Double maxWidth = (Double) resultMap.get(cache.MAP_KEY_MAX_WIDTH); Double maxHeight = (Double) resultMap.get(cache.MAP_KEY_MAX_HEIGHT); - String newPath = imageResizer.resizeImageIfNeeded(path, maxWidth, maxHeight); + int imageQuality = + resultMap.get(cache.MAP_KEY_IMAGE_QUALITY) == null + ? 100 + : (int) resultMap.get(cache.MAP_KEY_IMAGE_QUALITY); + + String newPath = imageResizer.resizeImageIfNeeded(path, maxWidth, maxHeight, imageQuality); resultMap.put(cache.MAP_KEY_PATH, newPath); } if (resultMap.isEmpty()) { @@ -516,12 +521,18 @@ private void handleImageResult(String path, boolean shouldDeleteOriginalIfScaled if (methodCall != null) { Double maxWidth = methodCall.argument("maxWidth"); Double maxHeight = methodCall.argument("maxHeight"); - String finalImagePath = imageResizer.resizeImageIfNeeded(path, maxWidth, maxHeight); + int imageQuality = + methodCall.argument("imageQuality") == null + ? 100 + : (int) methodCall.argument("imageQuality"); + + String finalImagePath = + imageResizer.resizeImageIfNeeded(path, maxWidth, maxHeight, imageQuality); finishWithSuccess(finalImagePath); //delete original file if scaled - if (!finalImagePath.equals(path) && shouldDeleteOriginalIfScaled) { + if (finalImagePath != null && !finalImagePath.equals(path) && shouldDeleteOriginalIfScaled) { new File(path).delete(); } } else { diff --git a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImageResizer.java b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImageResizer.java index f9bd3adb2e36..363bfec8281b 100644 --- a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImageResizer.java +++ b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImageResizer.java @@ -6,6 +6,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.util.Log; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; @@ -26,15 +27,17 @@ class ImageResizer { * *

If no resizing is needed, returns the path for the original image. */ - String resizeImageIfNeeded(String imagePath, Double maxWidth, Double maxHeight) { - boolean shouldScale = maxWidth != null || maxHeight != null; + String resizeImageIfNeeded( + String imagePath, Double maxWidth, Double maxHeight, int imageQuality) { + boolean shouldScale = + maxWidth != null || maxHeight != null || (imageQuality > -1 && imageQuality < 101); if (!shouldScale) { return imagePath; } try { - File scaledImage = resizedImage(imagePath, maxWidth, maxHeight); + File scaledImage = resizedImage(imagePath, maxWidth, maxHeight, imageQuality); exifDataCopier.copyExif(imagePath, scaledImage.getPath()); return scaledImage.getPath(); @@ -43,11 +46,16 @@ String resizeImageIfNeeded(String imagePath, Double maxWidth, Double maxHeight) } } - private File resizedImage(String path, Double maxWidth, Double maxHeight) throws IOException { + private File resizedImage(String path, Double maxWidth, Double maxHeight, int imageQuality) + throws IOException { Bitmap bmp = BitmapFactory.decodeFile(path); double originalWidth = bmp.getWidth() * 1.0; double originalHeight = bmp.getHeight() * 1.0; + if (imageQuality < 0 || imageQuality > 100) { + imageQuality = 100; + } + boolean hasMaxWidth = maxWidth != null; boolean hasMaxHeight = maxHeight != null; @@ -86,8 +94,15 @@ private File resizedImage(String path, Double maxWidth, Double maxHeight) throws Bitmap scaledBmp = Bitmap.createScaledBitmap(bmp, width.intValue(), height.intValue(), false); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); boolean saveAsPNG = bmp.hasAlpha(); + if (saveAsPNG) { + Log.d( + "ImageResizer", + "image_picker: compressing is not supported for type PNG. Returning the image with original quality"); + } scaledBmp.compress( - saveAsPNG ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG, 100, outputStream); + saveAsPNG ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG, + imageQuality, + outputStream); String[] pathParts = path.split("/"); String imageName = pathParts[pathParts.length - 1]; @@ -96,7 +111,6 @@ private File resizedImage(String path, Double maxWidth, Double maxHeight) throws FileOutputStream fileOutput = new FileOutputStream(imageFile); fileOutput.write(outputStream.toByteArray()); fileOutput.close(); - return imageFile; } } diff --git a/packages/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java b/packages/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java index c0ccfa0dd478..60e1167cd87a 100644 --- a/packages/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java +++ b/packages/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java @@ -26,6 +26,7 @@ public class ImagePickerDelegateTest { private static final double WIDTH = 10.0; private static final double HEIGHT = 10.0; + private static final int IMAGE_QUALITY = 100; @Mock Activity mockActivity; @Mock ImageResizer mockImageResizer; @@ -61,12 +62,13 @@ public void setUp() { when(mockFileUtils.getPathFromUri(any(Context.class), any(Uri.class))) .thenReturn("pathFromUri"); - when(mockImageResizer.resizeImageIfNeeded("pathFromUri", null, null)) + when(mockImageResizer.resizeImageIfNeeded("pathFromUri", null, null, IMAGE_QUALITY)) .thenReturn("originalPath"); - when(mockImageResizer.resizeImageIfNeeded("pathFromUri", WIDTH, HEIGHT)) + when(mockImageResizer.resizeImageIfNeeded("pathFromUri", WIDTH, HEIGHT, IMAGE_QUALITY)) .thenReturn("scaledPath"); - when(mockImageResizer.resizeImageIfNeeded("pathFromUri", WIDTH, null)).thenReturn("scaledPath"); - when(mockImageResizer.resizeImageIfNeeded("pathFromUri", null, HEIGHT)) + when(mockImageResizer.resizeImageIfNeeded("pathFromUri", WIDTH, null, IMAGE_QUALITY)) + .thenReturn("scaledPath"); + when(mockImageResizer.resizeImageIfNeeded("pathFromUri", null, HEIGHT, IMAGE_QUALITY)) .thenReturn("scaledPath"); mockFileUriResolver = new MockFileUriResolver(); diff --git a/packages/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m b/packages/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m index 5123dec11ece..a789853d32aa 100644 --- a/packages/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m +++ b/packages/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m @@ -64,12 +64,9 @@ + (NSData *)convertImage:(UIImage *)image usingType:(FLTImagePickerMIMEType)type quality:(nullable NSNumber *)quality { if (quality && type != FLTImagePickerMIMETypeJPEG) { - @throw [NSException - exceptionWithName:@"flutter_image_picker_convert_image_exception" - reason:[NSString stringWithFormat:@"quality is not available for type %@", - [FLTImagePickerMetaDataUtil - imageTypeSuffixFromType:type]] - userInfo:nil]; + NSLog(@"image_picker: compressing is not supported for type %@. Returning the image with " + @"original quality", + [FLTImagePickerMetaDataUtil imageTypeSuffixFromType:type]); } switch (type) { diff --git a/packages/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.h b/packages/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.h index e2b8357cf06f..417a6f9a7399 100644 --- a/packages/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.h +++ b/packages/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.h @@ -18,10 +18,13 @@ NS_ASSUME_NONNULL_BEGIN + (NSString *)saveImageWithOriginalImageData:(NSData *)originalImageData image:(UIImage *)image maxWidth:(nullable NSNumber *)maxWidth - maxHeight:(nullable NSNumber *)maxHeight; + maxHeight:(nullable NSNumber *)maxHeight + imageQuality:(nullable NSNumber *)imageQuality; // Save image with correct meta data and extention copied from image picker result info. -+ (NSString *)saveImageWithPickerInfo:(nullable NSDictionary *)info image:(UIImage *)image; ++ (NSString *)saveImageWithPickerInfo:(nullable NSDictionary *)info + image:(UIImage *)image + imageQuality:(NSNumber *)imageQuality; @end diff --git a/packages/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m b/packages/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m index bf22e0069278..59e9d51b9ed8 100644 --- a/packages/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m +++ b/packages/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m @@ -26,7 +26,8 @@ + (PHAsset *)getAssetFromImagePickerInfo:(NSDictionary *)info { + (NSString *)saveImageWithOriginalImageData:(NSData *)originalImageData image:(UIImage *)image maxWidth:(NSNumber *)maxWidth - maxHeight:(NSNumber *)maxHeight { + maxHeight:(NSNumber *)maxHeight + imageQuality:(NSNumber *)imageQuality { NSString *suffix = kFLTImagePickerDefaultSuffix; FLTImagePickerMIMEType type = kFLTImagePickerMIMETypeDefault; NSDictionary *metaData = nil; @@ -44,16 +45,23 @@ + (NSString *)saveImageWithOriginalImageData:(NSData *)originalImageData return [self saveImageWithMetaData:metaData gifInfo:gifInfo suffix:suffix]; } else { - return [self saveImageWithMetaData:metaData image:image suffix:suffix type:type]; + return [self saveImageWithMetaData:metaData + image:image + suffix:suffix + type:type + imageQuality:imageQuality]; } } -+ (NSString *)saveImageWithPickerInfo:(nullable NSDictionary *)info image:(UIImage *)image { ++ (NSString *)saveImageWithPickerInfo:(nullable NSDictionary *)info + image:(UIImage *)image + imageQuality:(NSNumber *)imageQuality { NSDictionary *metaData = info[UIImagePickerControllerMediaMetadata]; return [self saveImageWithMetaData:metaData image:image suffix:kFLTImagePickerDefaultSuffix - type:kFLTImagePickerMIMETypeDefault]; + type:kFLTImagePickerMIMETypeDefault + imageQuality:imageQuality]; } + (NSString *)saveImageWithMetaData:(NSDictionary *)metaData @@ -66,7 +74,8 @@ + (NSString *)saveImageWithMetaData:(NSDictionary *)metaData + (NSString *)saveImageWithMetaData:(NSDictionary *)metaData image:(UIImage *)image suffix:(NSString *)suffix - type:(FLTImagePickerMIMEType)type { + type:(FLTImagePickerMIMEType)type + imageQuality:(NSNumber *)imageQuality { CGImagePropertyOrientation orientation = (CGImagePropertyOrientation)[metaData[( __bridge NSString *)kCGImagePropertyOrientation] integerValue]; UIImage *newImage = [UIImage @@ -76,7 +85,9 @@ + (NSString *)saveImageWithMetaData:(NSDictionary *)metaData [FLTImagePickerMetaDataUtil getNormalizedUIImageOrientationFromCGImagePropertyOrientation:orientation]]; - NSData *data = [FLTImagePickerMetaDataUtil convertImage:newImage usingType:type quality:nil]; + NSData *data = [FLTImagePickerMetaDataUtil convertImage:newImage + usingType:type + quality:imageQuality]; if (metaData) { data = [FLTImagePickerMetaDataUtil updateMetaData:metaData toImage:data]; } diff --git a/packages/image_picker/ios/Classes/ImagePickerPlugin.m b/packages/image_picker/ios/Classes/ImagePickerPlugin.m index 18803d2e7fff..975c47778bbc 100644 --- a/packages/image_picker/ios/Classes/ImagePickerPlugin.m +++ b/packages/image_picker/ios/Classes/ImagePickerPlugin.m @@ -251,6 +251,15 @@ - (void)imagePickerController:(UIImagePickerController *)picker NSNumber *maxWidth = [_arguments objectForKey:@"maxWidth"]; NSNumber *maxHeight = [_arguments objectForKey:@"maxHeight"]; + NSNumber *imageQuality = [_arguments objectForKey:@"imageQuality"]; + + if (![imageQuality isKindOfClass:[NSNumber class]]) { + imageQuality = @1; + } else if (imageQuality.intValue < 0 || imageQuality.intValue > 100) { + imageQuality = [NSNumber numberWithInt:1]; + } else { + imageQuality = @([imageQuality floatValue] / 100); + } if (maxWidth != (id)[NSNull null] || maxHeight != (id)[NSNull null]) { image = [FLTImagePickerImageUtil scaledImage:image maxWidth:maxWidth maxHeight:maxHeight]; @@ -259,7 +268,7 @@ - (void)imagePickerController:(UIImagePickerController *)picker PHAsset *originalAsset = [FLTImagePickerPhotoAssetUtil getAssetFromImagePickerInfo:info]; if (!originalAsset) { // Image picked without an original asset (e.g. User took a photo directly) - [self saveImageWithPickerInfo:info image:image]; + [self saveImageWithPickerInfo:info image:image imageQuality:imageQuality]; } else { __weak typeof(self) weakSelf = self; [[PHImageManager defaultManager] @@ -271,7 +280,8 @@ - (void)imagePickerController:(UIImagePickerController *)picker [weakSelf saveImageWithOriginalImageData:imageData image:image maxWidth:maxWidth - maxHeight:maxHeight]; + maxHeight:maxHeight + imageQuality:imageQuality]; }]; } } @@ -289,17 +299,23 @@ - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { - (void)saveImageWithOriginalImageData:(NSData *)originalImageData image:(UIImage *)image maxWidth:(NSNumber *)maxWidth - maxHeight:(NSNumber *)maxHeight { + maxHeight:(NSNumber *)maxHeight + imageQuality:(NSNumber *)imageQuality { NSString *savedPath = [FLTImagePickerPhotoAssetUtil saveImageWithOriginalImageData:originalImageData image:image maxWidth:maxWidth - maxHeight:maxHeight]; + maxHeight:maxHeight + imageQuality:imageQuality]; [self handleSavedPath:savedPath]; } -- (void)saveImageWithPickerInfo:(NSDictionary *)info image:(UIImage *)image { - NSString *savedPath = [FLTImagePickerPhotoAssetUtil saveImageWithPickerInfo:info image:image]; +- (void)saveImageWithPickerInfo:(NSDictionary *)info + image:(UIImage *)image + imageQuality:(NSNumber *)imageQuality { + NSString *savedPath = [FLTImagePickerPhotoAssetUtil saveImageWithPickerInfo:info + image:image + imageQuality:imageQuality]; [self handleSavedPath:savedPath]; } diff --git a/packages/image_picker/lib/image_picker.dart b/packages/image_picker/lib/image_picker.dart index b224b6331ad8..a6ca94713ee3 100755 --- a/packages/image_picker/lib/image_picker.dart +++ b/packages/image_picker/lib/image_picker.dart @@ -26,21 +26,27 @@ class ImagePicker { /// Returns a [File] object pointing to the image that was picked. /// - /// The [source] argument controls where the image comes from. This can + /// The `source` argument controls where the image comes from. This can /// be either [ImageSource.camera] or [ImageSource.gallery]. /// - /// If specified, the image will be at most [maxWidth] wide and - /// [maxHeight] tall. Otherwise the image will be returned at it's + /// If specified, the image will be at most `maxWidth` wide and + /// `maxHeight` tall. Otherwise the image will be returned at it's /// original width and height. + /// The `imageQuality` argument modifies the quality of the image, ranging from 0-100 + /// where 100 is the original/max quality. If `imageQuality` is null, the image with + /// the original quality will be returned. Compression is only supportted for certain + /// image types such as JPEG. If compression is not supported for the image that is picked, + /// an warning message will be logged. /// /// In Android, the MainActivity can be destroyed for various reasons. If that happens, the result will be lost /// in this call. You can then call [retrieveLostData] when your app relaunches to retrieve the lost data. - static Future pickImage({ - @required ImageSource source, - double maxWidth, - double maxHeight, - }) async { + static Future pickImage( + {@required ImageSource source, + double maxWidth, + double maxHeight, + int imageQuality}) async { assert(source != null); + assert(imageQuality == null || (imageQuality >= 0 && imageQuality <= 100)); if (maxWidth != null && maxWidth < 0) { throw ArgumentError.value(maxWidth, 'maxWidth cannot be negative'); @@ -56,6 +62,7 @@ class ImagePicker { 'source': source.index, 'maxWidth': maxWidth, 'maxHeight': maxHeight, + 'imageQuality': imageQuality }, ); diff --git a/packages/image_picker/pubspec.yaml b/packages/image_picker/pubspec.yaml index f34c6708eae0..1cc244d831ce 100755 --- a/packages/image_picker/pubspec.yaml +++ b/packages/image_picker/pubspec.yaml @@ -6,7 +6,7 @@ authors: - Rhodes Davis Jr. homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker -version: 0.6.0+20 +version: 0.6.1 flutter: plugin: diff --git a/packages/image_picker/test/image_picker_test.dart b/packages/image_picker/test/image_picker_test.dart index 40226afb77ce..7d962e6b916b 100644 --- a/packages/image_picker/test/image_picker_test.dart +++ b/packages/image_picker/test/image_picker_test.dart @@ -34,11 +34,13 @@ void main() { 'source': 0, 'maxWidth': null, 'maxHeight': null, + 'imageQuality': null }), isMethodCall('pickImage', arguments: { 'source': 1, 'maxWidth': null, 'maxHeight': null, + 'imageQuality': null }), ], ); @@ -59,6 +61,15 @@ void main() { maxWidth: 10.0, maxHeight: 20.0, ); + await ImagePicker.pickImage( + source: ImageSource.camera, maxWidth: 10.0, imageQuality: 70); + await ImagePicker.pickImage( + source: ImageSource.camera, maxHeight: 10.0, imageQuality: 70); + await ImagePicker.pickImage( + source: ImageSource.camera, + maxWidth: 10.0, + maxHeight: 20.0, + imageQuality: 70); expect( log, @@ -67,21 +78,43 @@ void main() { 'source': 0, 'maxWidth': null, 'maxHeight': null, + 'imageQuality': null + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': null + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': null + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': null }), isMethodCall('pickImage', arguments: { 'source': 0, 'maxWidth': 10.0, 'maxHeight': null, + 'imageQuality': 70 }), isMethodCall('pickImage', arguments: { 'source': 0, 'maxWidth': null, 'maxHeight': 10.0, + 'imageQuality': 70 }), isMethodCall('pickImage', arguments: { 'source': 0, 'maxWidth': 10.0, 'maxHeight': 20.0, + 'imageQuality': 70 }), ], );