From f1c468051c582bd2d351a04fd12e0f1510941986 Mon Sep 17 00:00:00 2001 From: jesusrp98 Date: Sun, 17 Jan 2021 20:53:59 +0100 Subject: [PATCH 1/4] Initial implementation --- .../lib/image_picker_for_web.dart | 58 ++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index e50b4aad3c8d..2f740750ee82 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -37,9 +37,63 @@ class ImagePickerPlugin extends ImagePickerPlatform { double maxHeight, int imageQuality, CameraDevice preferredCameraDevice = CameraDevice.rear, - }) { + }) async { String capture = computeCaptureAttribute(source, preferredCameraDevice); - return pickFile(accept: _kAcceptImageMimeType, capture: capture); + return pickFile( + accept: _kAcceptImageMimeType, + capture: await _resizeImage( + capture, + maxWidth.toInt(), + maxHeight.toInt(), + imageQuality, + ), + ); + } + + static Future _resizeImage( + String src, + int maxWidth, + int maxHeight, + int imageQuality, + ) { + final completer = Completer(); + final img = html.ImageElement(); + img.onError.listen((event) { + completer.complete(""); + }); + img.onLoad.listen((event) { + final canvas = html.CanvasElement(); + final ctx = canvas.context2D; + double ratio = 1; + + if (img.width > img.height) { + if (img.width > maxWidth) ratio = maxWidth / img.width; + } else if (img.height > maxWidth) { + ratio = maxWidth / img.height; + } + if (img.width > img.height) { + if (img.width < maxHeight) ratio = maxHeight / img.width; + } else if (img.height < maxHeight) { + ratio = maxHeight / img.height; + } + + canvas.height = (img.height * ratio).floor(); + canvas.width = (img.width * ratio).floor(); + // Draw the image to canvas and resize + ctx.drawImageScaled(img, 0, 0, canvas.width, canvas.height); + final base64 = canvas.toDataUrl("image/png", imageQuality / 100); + completer.complete(base64); + }); + img.src = src; + // make sure the load event fires for cached images too + if (img.complete) { + // Flush cache + img.src = + 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=='; + // Try again + img.src = src; + } + return completer.future; } @override From 4e828e5e2a4e25fdc1c7b27d686828f6342e4f11 Mon Sep 17 00:00:00 2001 From: jesusrp98 Date: Fri, 22 Jan 2021 13:07:26 +0100 Subject: [PATCH 2/4] Applied several suggestions to implementation --- .../lib/image_picker_for_web.dart | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 2f740750ee82..b211a978482f 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -39,28 +39,32 @@ class ImagePickerPlugin extends ImagePickerPlatform { CameraDevice preferredCameraDevice = CameraDevice.rear, }) async { String capture = computeCaptureAttribute(source, preferredCameraDevice); - return pickFile( + + final pickedFile = await pickFile( accept: _kAcceptImageMimeType, - capture: await _resizeImage( - capture, - maxWidth.toInt(), - maxHeight.toInt(), - imageQuality, - ), + capture: capture, ); + + if (maxWidth != null && maxHeight != null && imageQuality != null) { + return _resizeImage(pickedFile.path, maxWidth, maxHeight, imageQuality); + } else { + return pickedFile; + } } - static Future _resizeImage( + static Future _resizeImage( String src, - int maxWidth, - int maxHeight, + double maxWidth, + double maxHeight, int imageQuality, ) { - final completer = Completer(); + final completer = Completer(); final img = html.ImageElement(); + img.onError.listen((event) { - completer.complete(""); + completer.complete(PickedFile('')); }); + img.onLoad.listen((event) { final canvas = html.CanvasElement(); final ctx = canvas.context2D; @@ -79,11 +83,13 @@ class ImagePickerPlugin extends ImagePickerPlatform { canvas.height = (img.height * ratio).floor(); canvas.width = (img.width * ratio).floor(); + // Draw the image to canvas and resize ctx.drawImageScaled(img, 0, 0, canvas.width, canvas.height); - final base64 = canvas.toDataUrl("image/png", imageQuality / 100); - completer.complete(base64); + final base64 = canvas.toDataUrl('image/png', imageQuality / 100); + completer.complete(PickedFile(base64)); }); + img.src = src; // make sure the load event fires for cached images too if (img.complete) { @@ -93,6 +99,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { // Try again img.src = src; } + return completer.future; } From 3d84e183cbe4fb8a970eee217beb2b6dfacbe21d Mon Sep 17 00:00:00 2001 From: jesusrp98 Date: Mon, 25 Jan 2021 19:47:07 +0100 Subject: [PATCH 3/4] Improved algorithm --- .../lib/image_picker_for_web.dart | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index b211a978482f..9aa50ce5fcfa 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -1,9 +1,10 @@ import 'dart:async'; import 'dart:html' as html; +import 'dart:math' as math; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; -import 'package:meta/meta.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; +import 'package:meta/meta.dart'; final String _kImagePickerInputsDomId = '__image_picker_web-file-input'; final String _kAcceptImageMimeType = 'image/*'; @@ -45,7 +46,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { capture: capture, ); - if (maxWidth != null && maxHeight != null && imageQuality != null) { + if (maxWidth != null && maxHeight != null) { return _resizeImage(pickedFile.path, maxWidth, maxHeight, imageQuality); } else { return pickedFile; @@ -68,21 +69,34 @@ class ImagePickerPlugin extends ImagePickerPlatform { img.onLoad.listen((event) { final canvas = html.CanvasElement(); final ctx = canvas.context2D; - double ratio = 1; - if (img.width > img.height) { - if (img.width > maxWidth) ratio = maxWidth / img.width; - } else if (img.height > maxWidth) { - ratio = maxWidth / img.height; + var width = math.min(img.width, maxWidth); + var height = math.min(img.height, maxHeight); + + if (!_isImageQualityValid(imageQuality)) { + imageQuality = 100; } - if (img.width > img.height) { - if (img.width < maxHeight) ratio = maxHeight / img.width; - } else if (img.height < maxHeight) { - ratio = maxHeight / img.height; + + final shouldDownscale = maxWidth < img.width || maxHeight < img.height; + if (shouldDownscale) { + final downscaledWidth = (height / img.height) * img.width; + final downscaledHeight = (width / img.width) * img.height; + + if (width < height) { + height = downscaledHeight; + } else if (height < width) { + width = downscaledWidth; + } else { + if (img.width < img.height) { + width = downscaledWidth; + } else if (img.height < img.width) { + height = downscaledHeight; + } + } } - canvas.height = (img.height * ratio).floor(); - canvas.width = (img.width * ratio).floor(); + canvas.height = height.floor(); + canvas.width = width.floor(); // Draw the image to canvas and resize ctx.drawImageScaled(img, 0, 0, canvas.width, canvas.height); @@ -181,6 +195,10 @@ class ImagePickerPlugin extends ImagePickerPlatform { return _completer.future; } + static bool _isImageQualityValid(int imageQuality) { + return imageQuality != null && imageQuality > 0 && imageQuality < 100; + } + /// Initializes a DOM container where we can host input elements. html.Element _ensureInitialized(String id) { var target = html.querySelector('#${id}'); From 0b9057cad5d75f3453c8c950cec9401367a4d915 Mon Sep 17 00:00:00 2001 From: jesusrp98 Date: Mon, 25 Jan 2021 19:49:02 +0100 Subject: [PATCH 4/4] Added a new completer check --- .../lib/image_picker_for_web.dart | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 9aa50ce5fcfa..7140defddf04 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -67,41 +67,43 @@ class ImagePickerPlugin extends ImagePickerPlatform { }); img.onLoad.listen((event) { - final canvas = html.CanvasElement(); - final ctx = canvas.context2D; + if (img.width > 1 && img.height > 1) { + final canvas = html.CanvasElement(); + final ctx = canvas.context2D; - var width = math.min(img.width, maxWidth); - var height = math.min(img.height, maxHeight); + var width = math.min(img.width, maxWidth); + var height = math.min(img.height, maxHeight); - if (!_isImageQualityValid(imageQuality)) { - imageQuality = 100; - } + if (!_isImageQualityValid(imageQuality)) { + imageQuality = 100; + } - final shouldDownscale = maxWidth < img.width || maxHeight < img.height; - if (shouldDownscale) { - final downscaledWidth = (height / img.height) * img.width; - final downscaledHeight = (width / img.width) * img.height; - - if (width < height) { - height = downscaledHeight; - } else if (height < width) { - width = downscaledWidth; - } else { - if (img.width < img.height) { - width = downscaledWidth; - } else if (img.height < img.width) { + final shouldDownscale = maxWidth < img.width || maxHeight < img.height; + if (shouldDownscale) { + final downscaledWidth = (height / img.height) * img.width; + final downscaledHeight = (width / img.width) * img.height; + + if (width < height) { height = downscaledHeight; + } else if (height < width) { + width = downscaledWidth; + } else { + if (img.width < img.height) { + width = downscaledWidth; + } else if (img.height < img.width) { + height = downscaledHeight; + } } } - } - canvas.height = height.floor(); - canvas.width = width.floor(); + canvas.height = height.floor(); + canvas.width = width.floor(); - // Draw the image to canvas and resize - ctx.drawImageScaled(img, 0, 0, canvas.width, canvas.height); - final base64 = canvas.toDataUrl('image/png', imageQuality / 100); - completer.complete(PickedFile(base64)); + // Draw the image to canvas and resize + ctx.drawImageScaled(img, 0, 0, canvas.width, canvas.height); + final base64 = canvas.toDataUrl('image/png', imageQuality / 100); + completer.complete(PickedFile(base64)); + } }); img.src = src;