Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add support for YUV_420_888 Image format. #732

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 35 additions & 12 deletions packages/example/lib/vision_detector_views/camera_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -358,29 +358,52 @@ class _CameraViewState extends State<CameraView> {

// get image format
final format = InputImageFormatValue.fromRawValue(image.format.raw);
// validate format depending on platform
// only supported formats:
// * nv21 for Android
// * bgra8888 for iOS
if (format == null ||
(Platform.isAndroid && format != InputImageFormat.nv21) ||
if (format == null) {
print('could not find format from raw value: $image.format.raw');
return null;
}
// Validate format depending on platform
final androidSupportedFormats = [
InputImageFormat.nv21,
InputImageFormat.yv12,
InputImageFormat.yuv_420_888
];
if ((Platform.isAndroid && !androidSupportedFormats.contains(format)) ||
(Platform.isIOS && format != InputImageFormat.bgra8888)) {
print('image format is not supported: $format');
return null;
}

// since format is constraint to nv21 or bgra8888, both only have one plane
if (image.planes.length != 1) return null;
final plane = image.planes.first;
// Compile a flat list of all image data. For image formats with multiple planes,
// takes some copying.
final Uint8List bytes = image.planes.length == 1
? image.planes.first.bytes
: _concatenatePlanes(image);

// compose InputImage using bytes
return InputImage.fromBytes(
bytes: plane.bytes,
bytes: bytes,
metadata: InputImageMetadata(
size: Size(image.width.toDouble(), image.height.toDouble()),
rotation: rotation, // used only in Android
format: format, // used only in iOS
bytesPerRow: plane.bytesPerRow, // used only in iOS
format: format,
bytesPerRow: image.planes.first.bytesPerRow, // used only in iOS
),
);
}

Uint8List _concatenatePlanes(CameraImage image) {
int length = 0;
for (final Plane p in image.planes) {
length += p.bytes.length;
}

final Uint8List bytes = Uint8List(length);
int offset = 0;
for (final Plane p in image.planes) {
bytes.setRange(offset, offset + p.bytes.length, p.bytes);
offset += p.bytes.length;
}
return bytes;
}
}
82 changes: 37 additions & 45 deletions packages/example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,8 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.11.0+2"
camera_android:
dependency: "direct main"
description:
name: camera_android
sha256: "19b7226387218864cb2388e1ad5db7db50d065222f5511254b03fc397dd21a5e"
url: "https://pub.dev"
source: hosted
version: "0.10.9+17"
camera_android_camerax:
dependency: transitive
dependency: "direct main"
description:
name: camera_android_camerax
sha256: "2bb0724371bae3c0889d7e0b1665357e4aa6ba6c8d32ffa3e178098ba81ed3df"
Expand All @@ -45,18 +37,18 @@ packages:
dependency: transitive
description:
name: camera_avfoundation
sha256: "7c28969a975a7eb2349bc2cb2dfe3ad218a33dba9968ecfb181ce08c87486655"
sha256: "3f81ee3e88a79b0b010f0233d42625926299551b05d5dc995267a0b35bc33247"
url: "https://pub.dev"
source: hosted
version: "0.9.17+3"
version: "0.9.18"
camera_platform_interface:
dependency: transitive
description:
name: camera_platform_interface
sha256: b3ede1f171532e0d83111fe0980b46d17f1aa9788a07a2fbed07366bbdbb9061
sha256: "953e7baed3a7c8fae92f7200afeb2be503ff1a17c3b4e4ed7b76f008c2810a31"
url: "https://pub.dev"
source: hosted
version: "2.8.0"
version: "2.9.0"
camera_web:
dependency: transitive
description:
Expand Down Expand Up @@ -117,10 +109,10 @@ packages:
dependency: transitive
description:
name: file_selector_linux
sha256: "712ce7fab537ba532c8febdb1a8f167b32441e74acd68c3ccb2e36dcb52c4ab2"
sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33"
url: "https://pub.dev"
source: hosted
version: "0.9.3"
version: "0.9.3+2"
file_selector_macos:
dependency: transitive
description:
Expand Down Expand Up @@ -162,18 +154,18 @@ packages:
dependency: "direct main"
description:
name: flutter_pdfview
sha256: "6b625b32a9102780236554dff42f2d798b4627704ab4a3153c07f2134a52b697"
sha256: "2e3fa359524e9865ec25a64593b65092b4a9974c5871228c1a771300a003d150"
url: "https://pub.dev"
source: hosted
version: "1.3.3"
version: "1.4.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398"
sha256: "615a505aef59b151b46bbeef55b36ce2b6ed299d160c51d84281946f0aa0ce0e"
url: "https://pub.dev"
source: hosted
version: "2.0.23"
version: "2.0.24"
flutter_test:
dependency: "direct dev"
description: flutter
Expand Down Expand Up @@ -308,10 +300,10 @@ packages:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
version: "4.1.2"
image_picker:
dependency: "direct main"
description:
Expand All @@ -324,26 +316,26 @@ packages:
dependency: transitive
description:
name: image_picker_android
sha256: d3e5e00fdfeca8fd4ffb3227001264d449cc8950414c2ff70b0e06b9c628e643
sha256: b62d34a506e12bb965e824b6db4fbf709ee4589cf5d3e99b45ab2287b008ee0c
url: "https://pub.dev"
source: hosted
version: "0.8.12+15"
version: "0.8.12+20"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50"
sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.6"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
sha256: "6703696ad49f5c3c8356d576d7ace84d1faf459afb07accbb0fae780753ff447"
sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100"
url: "https://pub.dev"
source: hosted
version: "0.8.12"
version: "0.8.12+2"
image_picker_linux:
dependency: transitive
description:
Expand All @@ -364,10 +356,10 @@ packages:
dependency: transitive
description:
name: image_picker_platform_interface
sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80"
sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0"
url: "https://pub.dev"
source: hosted
version: "2.10.0"
version: "2.10.1"
image_picker_windows:
dependency: transitive
description:
Expand Down Expand Up @@ -404,10 +396,10 @@ packages:
dependency: transitive
description:
name: lints
sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413"
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
url: "https://pub.dev"
source: hosted
version: "5.0.0"
version: "5.1.1"
matcher:
dependency: transitive
description:
Expand Down Expand Up @@ -436,10 +428,10 @@ packages:
dependency: transitive
description:
name: mime
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
url: "https://pub.dev"
source: hosted
version: "1.0.6"
version: "2.0.0"
path:
dependency: "direct main"
description:
Expand All @@ -452,26 +444,26 @@ packages:
dependency: "direct main"
description:
name: path_provider
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.1.5"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2"
url: "https://pub.dev"
source: hosted
version: "2.2.12"
version: "2.2.15"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
version: "2.4.1"
path_provider_linux:
dependency: transitive
description:
Expand Down Expand Up @@ -500,10 +492,10 @@ packages:
dependency: transitive
description:
name: platform
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
url: "https://pub.dev"
source: hosted
version: "3.1.5"
version: "3.1.6"
plugin_platform_interface:
dependency: transitive
description:
Expand Down Expand Up @@ -545,10 +537,10 @@ packages:
dependency: transitive
description:
name: stream_transform
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.1"
string_scanner:
dependency: transitive
description:
Expand Down Expand Up @@ -577,10 +569,10 @@ packages:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
url: "https://pub.dev"
source: hosted
version: "1.3.2"
version: "1.4.0"
vector_math:
dependency: transitive
description:
Expand Down
3 changes: 1 addition & 2 deletions packages/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ dependencies:
flutter_pdfview: ^1.3.3
image_picker: ^1.1.2
camera: ^0.11.0+2
# The default Android implementation from camera_android_camerax doesn't support the required image format.
camera_android: ^0.10.9+17
camera_android_camerax: 0.6.11 # Due to https://github.com/flutter/flutter/issues/154241
path: ^1.9.0
path_provider: ^2.1.4

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.flutter.plugin.common.MethodChannel;

public class BarcodeScanner implements MethodChannel.MethodCallHandler {

private static final String START = "vision#startBarcodeScanner";
private static final String CLOSE = "vision#closeBarcodeScanner";

Expand Down Expand Up @@ -67,8 +68,11 @@ private com.google.mlkit.vision.barcode.BarcodeScanner initialize(MethodCall cal

private void handleDetection(MethodCall call, final MethodChannel.Result result) {
Map<String, Object> imageData = call.argument("imageData");
InputImage inputImage = InputImageConverter.getInputImageFromData(imageData, context, result);
if (inputImage == null) return;
InputImageConverter converter = new InputImageConverter();
InputImage inputImage = converter.getInputImageFromData(imageData, context, result);
if (inputImage == null) {
return;
}

String id = call.argument("id");
com.google.mlkit.vision.barcode.BarcodeScanner barcodeScanner = instances.get(id);
Expand Down Expand Up @@ -191,7 +195,9 @@ private void handleDetection(MethodCall call, final MethodChannel.Result result)
}
result.success(barcodeList);
})
.addOnFailureListener(e -> result.error("BarcodeDetectorError", e.toString(), null));
.addOnFailureListener(e -> result.error("BarcodeDetectorError", e.toString(), e))
// Closing is necessary for both success and failure.
.addOnCompleteListener(r -> converter.close());
}

private void addPoints(Point[] cornerPoints, List<Map<String, Integer>> points) {
Expand All @@ -205,7 +211,9 @@ private void addPoints(Point[] cornerPoints, List<Map<String, Integer>> points)

private Map<String, Integer> getBoundingPoints(@Nullable Rect rect) {
Map<String, Integer> frame = new HashMap<>();
if (rect == null) return frame;
if (rect == null) {
return frame;
}
frame.put("left", rect.left);
frame.put("right", rect.right);
frame.put("top", rect.top);
Expand All @@ -216,7 +224,9 @@ private Map<String, Integer> getBoundingPoints(@Nullable Rect rect) {
private void closeDetector(MethodCall call) {
String id = call.argument("id");
com.google.mlkit.vision.barcode.BarcodeScanner barcodeScanner = instances.get(id);
if (barcodeScanner == null) return;
if (barcodeScanner == null) {
return;
}
barcodeScanner.close();
instances.remove(id);
}
Expand Down
Loading