From b1c4db8dc8824b16bff01f68864c515dbd785e3b Mon Sep 17 00:00:00 2001 From: Khoren Markosyan Date: Wed, 30 Aug 2023 16:23:54 +0400 Subject: [PATCH] updated image to v4 --- CHANGELOG.md | 4 ++ example/pubspec.lock | 86 ++++++++++++------------ lib/src/ui/writer_widget.dart | 7 +- lib/src/utils/image_converter.dart | 102 ++++++++++++++--------------- pubspec.yaml | 4 +- 5 files changed, 104 insertions(+), 99 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a71ee32..688d518 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.4.0 + +* Updated Image to v4 + ## 1.3.2 * Conditionally add namespace for AGP 8 support diff --git a/example/pubspec.lock b/example/pubspec.lock index 15e0d4e..2487183 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -29,42 +29,42 @@ packages: dependency: transitive description: name: camera - sha256: b4cede7c66f44fa476272d21bfe143d5f32e75de1ea56f737e3eaf982da23bab + sha256: f63f2687fb1795c36f7c57b18a03071880eabb0fd8b5291b0fcd3fb979cb0fb1 url: "https://pub.dev" source: hosted - version: "0.10.5+3" + version: "0.10.5+4" camera_android: dependency: transitive description: name: camera_android - sha256: "61d62676708f187fb89fb14b371f87470343ba3cb26d08fc358e4f8a18e13150" + sha256: ed4f645848074166fc3b8e20350f83ca07e09a2becc1e185040ee561f955d4df url: "https://pub.dev" source: hosted - version: "0.10.8+6" + version: "0.10.8+8" camera_avfoundation: dependency: transitive description: name: camera_avfoundation - sha256: "332747f20cf911980e38c8442108102d4456752711781108fda237635baf362c" + sha256: "718b60ed2e22b4067fe6e2c0e9ebe2856c2de5c8b1289ba95d10db85b0b00bc2" url: "https://pub.dev" source: hosted - version: "0.9.13+3" + version: "0.9.13+4" camera_platform_interface: dependency: transitive description: name: camera_platform_interface - sha256: "60fa0bb62a4f3bf3a7c413e31e4cd01b69c779ccc8e4668904a24581b86c316b" + sha256: "8734d1c682f034bdb12d0d6ff379b0535a9b8e44266b530025bf8266d6a62f28" url: "https://pub.dev" source: hosted - version: "2.5.1" + version: "2.5.2" camera_web: dependency: transitive description: name: camera_web - sha256: "894df2a4e9ddd77ffecee9553d5980eeabb8bf09d98e53934859e67dc367933b" + sha256: "012c82efeb6b69626f1cf7a37c5277c1032428bcae98c7ab6401ff5e91eca628" url: "https://pub.dev" source: hosted - version: "0.3.2+1" + version: "0.3.2+2" characters: dependency: transitive description: @@ -101,10 +101,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" + sha256: fd832b5384d0d6da4f6df60b854d33accaaeb63aa9e10e736a87381f08dee2cb url: "https://pub.dev" source: hosted - version: "0.3.3+4" + version: "0.3.3+5" crypto: dependency: transitive description: @@ -133,34 +133,34 @@ packages: dependency: transitive description: name: file_selector_linux - sha256: "770eb1ab057b5ae4326d1c24cc57710758b9a46026349d021d6311bd27580046" + sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492" url: "https://pub.dev" source: hosted - version: "0.9.2" + version: "0.9.2+1" file_selector_macos: dependency: transitive description: name: file_selector_macos - sha256: "4ada532862917bf16e3adb3891fe3a5917a58bae03293e497082203a80909412" + sha256: "182c3f8350cee659f7b115e956047ee3dc672a96665883a545e81581b9a82c72" url: "https://pub.dev" source: hosted - version: "0.9.3+1" + version: "0.9.3+2" file_selector_platform_interface: dependency: transitive description: name: file_selector_platform_interface - sha256: "412705a646a0ae90f33f37acfae6a0f7cbc02222d6cd34e479421c3e74d3853c" + sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262" url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.6.1" file_selector_windows: dependency: transitive description: name: file_selector_windows - sha256: "1372760c6b389842b77156203308940558a2817360154084368608413835fc26" + sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0 url: "https://pub.dev" source: hosted - version: "0.9.3" + version: "0.9.3+1" flutter: dependency: "direct main" description: flutter @@ -170,18 +170,18 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" + sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.0.3" flutter_plugin_android_lifecycle: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "950e77c2bbe1692bc0874fc7fb491b96a4dc340457f4ea1641443d0a6c1ea360" + sha256: f185ac890306b5779ecbd611f52502d8d4d63d27703ef73161ca0407e815f02c url: "https://pub.dev" source: hosted - version: "2.0.15" + version: "2.0.16" flutter_test: dependency: "direct dev" description: flutter @@ -198,7 +198,7 @@ packages: path: ".." relative: true source: path - version: "1.3.1" + version: "1.3.2" http: dependency: transitive description: @@ -219,74 +219,74 @@ packages: dependency: transitive description: name: image - sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6" + sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "4.0.17" image_picker: dependency: transitive description: name: image_picker - sha256: "841837258e0b42c80946c43443054fc726f5e8aa84a97f363eb9ef0d45b33c14" + sha256: "866724408a53806722893012bc8081ed78dc756b36f19e37712819445da3ad3a" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.0.3" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: "8179b54039b50eee561676232304f487602e2950ffb3e8995ed9034d6505ca34" + sha256: d32a997bcc4ee135aebca8e272b7c517927aa65a74b9c60a81a2764ef1a0462d url: "https://pub.dev" source: hosted - version: "0.8.7+4" + version: "0.8.7+5" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "8b6c160cdbe572199103a091c783685b236110e4a0fd7a4947f32ff5b7da8765" + sha256: "50bc9ae6a77eea3a8b11af5eb6c661eeb858fdd2f734c2a4fd17086922347ef7" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.1" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: b3e2f21feb28b24dd73a35d7ad6e83f568337c70afab5eabac876e23803f264b + sha256: c5538cacefacac733c724be7484377923b476216ad1ead35a0d2eadcdc0fc497 url: "https://pub.dev" source: hosted - version: "0.8.8" + version: "0.8.8+2" image_picker_linux: dependency: transitive description: name: image_picker_linux - sha256: "02cbc21fe1706b97942b575966e5fbbeaac535e76deef70d3a242e4afb857831" + sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa" url: "https://pub.dev" source: hosted - version: "0.2.1" + version: "0.2.1+1" image_picker_macos: dependency: transitive description: name: image_picker_macos - sha256: cee2aa86c56780c13af2c77b5f2f72973464db204569e1ba2dd744459a065af4 + sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" url: "https://pub.dev" source: hosted - version: "0.2.1" + version: "0.2.1+1" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface - sha256: c1134543ae2187e85299996d21c526b2f403854994026d575ae4cf30d7bb2a32 + sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514 url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.9.1" image_picker_windows: dependency: transitive description: name: image_picker_windows - sha256: c3066601ea42113922232c7b7b3330a2d86f029f685bba99d82c30e799914952 + sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" url: "https://pub.dev" source: hosted - version: "0.2.1" + version: "0.2.1+1" js: dependency: transitive description: diff --git a/lib/src/ui/writer_widget.dart b/lib/src/ui/writer_widget.dart index 11e3903..ee57b57 100644 --- a/lib/src/ui/writer_widget.dart +++ b/lib/src/ui/writer_widget.dart @@ -278,9 +278,10 @@ class _WriterWidgetState extends State if (result.isValid && result.data != null) { try { final imglib.Image img = imglib.Image.fromBytes( - width, - height, - result.data!, + width: width, + height: height, + bytes: result.data!.buffer, + numChannels: 4, ); final Uint8List encodedBytes = Uint8List.fromList( imglib.encodeJpg(img), diff --git a/lib/src/utils/image_converter.dart b/lib/src/utils/image_converter.dart index 8a58054..4327bce 100644 --- a/lib/src/utils/image_converter.dart +++ b/lib/src/utils/image_converter.dart @@ -9,60 +9,19 @@ import 'package:image/image.dart' as imglib; Future convertImage(CameraImage image) async { try { - late imglib.Image img; if (image.format.group == ImageFormatGroup.yuv420) { - // img = convertYUV420(image); return image.planes.first.bytes; } else if (image.format.group == ImageFormatGroup.bgra8888) { - img = convertBGRA8888(image); + final Uint32List bytes = + _getBGRABytes(image.planes[0].bytes, image.width, image.height); + return _getLuminanceBytes(bytes, image.width, image.height); } - return img.getBytes(format: imglib.Format.luminance); //.toUint8List(); } catch (e) { debugPrint('>>>>>>>>>>>> ERROR: $e'); } return Uint8List(0); } -imglib.Image convertBGRA8888(CameraImage image) { - return imglib.Image.fromBytes( - image.width, - image.height, - image.planes[0].bytes, - format: imglib.Format.bgra, - // format: imglib.Format.int8, - // order: imglib.ChannelOrder.bgra, - ); -} - -// ignore: unused_element -// imglib.Image convertYUV420(CameraImage image) { -// final imglib.Image img = imglib.Image( -// width: image.width, -// height: image.height, -// ); // Create Image buffer - -// final Plane plane = image.planes[0]; -// const int shift = 0xFF << 24; - -// // Fill image buffer with plane[0] from YUV420_888 -// for (int x = 0; x < image.width; x++) { -// for (int planeOffset = 0; -// planeOffset < image.height * image.width; -// planeOffset += image.width) { -// final int pixelColor = plane.bytes[planeOffset + x]; -// // color: 0x FF FF FF FF -// // A B G R -// // Calculate pixel color -// final int newVal = -// shift | (pixelColor << 16) | (pixelColor << 8) | pixelColor; - -// // img.data?.buffer[planeOffset + x] = newVal; -// } -// } - -// return img; -// } - Uint8List invertImage(Uint8List bytes) { final Uint8List invertedBytes = Uint8List.fromList(bytes); for (int i = 0; i < invertedBytes.length; i++) { @@ -85,11 +44,52 @@ imglib.Image resizeToMaxSize(imglib.Image image, int? maxSize) { // get the bytes of the image in grayscale format (luminance) like v3 Uint8List grayscaleBytes(imglib.Image image) { - return image.getBytes(format: imglib.Format.luminance); - // final imglib.Image imgRgba8 = image.convert( - // format: imglib.Format.uint8, - // numChannels: 1, - // ); // Make sure it's an RGBA 32-bit image like v3 - // imglib.grayscale(imgRgba8); // map the pixels to grayscale (luminance) - // return imgRgba8.getBytes(); + final Uint32List bytes = + _getBGRABytes(image.buffer.asUint8List(), image.width, image.height); + return _getLuminanceBytes(bytes, image.width, image.height); } + +Uint32List _getBGRABytes(Uint8List bytes, int width, int height) { + final Uint8List input = + bytes is Uint32List ? Uint8List.view(bytes.buffer) : bytes; + + final Uint32List data = Uint32List(width * height); + final Uint8List rgba = Uint8List.view(data.buffer); + + for (int i = 0, len = input.length; i < len; i += 4) { + rgba[i + 0] = input[i + 2]; + rgba[i + 1] = input[i + 1]; + rgba[i + 2] = input[i + 0]; + rgba[i + 3] = input[i + 3]; + } + return data; +} + +Uint8List _getLuminanceBytes(Uint32List data, int width, int height) { + final Uint8List bytes = Uint8List(width * height); + for (int i = 0, len = data.length; i < len; ++i) { + bytes[i] = _getLuminance(data[i]); + } + return bytes; +} + +/// Returns the luminance (grayscale) value of the [color]. +int _getLuminance(int color) { + final int r = _getRed(color); + final int g = _getGreen(color); + final int b = _getBlue(color); + return _getLuminanceRgb(r, g, b); +} + +/// Returns the luminance (grayscale) value of the color. +int _getLuminanceRgb(int r, int g, int b) => + (0.299 * r + 0.587 * g + 0.114 * b).round(); + +/// Get the red channel from the [color]. +int _getRed(int color) => color & 0xff; + +/// Get the green channel from the [color]. +int _getGreen(int color) => (color >> 8) & 0xff; + +/// Get the blue channel from the [color]. +int _getBlue(int color) => (color >> 16) & 0xff; diff --git a/pubspec.yaml b/pubspec.yaml index 0b32564..0130443 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_zxing description: A barcode scanner and generator natively in Flutter with Dart FFI based on ZXing. -version: 1.3.2 +version: 1.4.0 repository: https://github.com/khoren93/flutter_zxing environment: @@ -12,7 +12,7 @@ dependencies: ffi: ^2.0.0 flutter: sdk: flutter - image: ^3.0.0 + image: ^4.0.0 image_picker: ^1.0.0 dev_dependencies: