From 327d0dfb57597143ba53a37521dd32ab5bb7f644 Mon Sep 17 00:00:00 2001 From: panmari Date: Wed, 8 Jan 2025 07:24:53 +0100 Subject: [PATCH] Adds better error handling for image format YUV_420_888. This format can not be read by the InputImage.fromByteArray API, as documented at https://developers.google.com/android/reference/com/google/mlkit/vision/common/InputImage#public-static-inputimage-frombytearray-byte[]-bytearray,-int-width,-int-height,-int-rotationdegrees,-int-format. Converting the bytes received here to the right type (android.media.Image) is non-trivial. Additionally improving error handling by passing along stack traces when possible. --- .../InputImageConverter.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/google_mlkit_commons/android/src/main/java/com/google_mlkit_commons/InputImageConverter.java b/packages/google_mlkit_commons/android/src/main/java/com/google_mlkit_commons/InputImageConverter.java index 1783eb3c..33405ab4 100644 --- a/packages/google_mlkit_commons/android/src/main/java/com/google_mlkit_commons/InputImageConverter.java +++ b/packages/google_mlkit_commons/android/src/main/java/com/google_mlkit_commons/InputImageConverter.java @@ -1,6 +1,7 @@ package com.google_mlkit_commons; import android.content.Context; +import android.graphics.ImageFormat; import android.net.Uri; import android.util.Log; @@ -17,8 +18,8 @@ public class InputImageConverter { //Returns an [InputImage] from the image data received public static InputImage getInputImageFromData(Map imageData, - Context context, - MethodChannel.Result result) { + Context context, + MethodChannel.Result result) { //Differentiates whether the image data is a path for a image file or contains image data in form of bytes String model = (String) imageData.get("type"); InputImage inputImage; @@ -29,7 +30,7 @@ public static InputImage getInputImageFromData(Map imageData, } catch (IOException e) { Log.e("ImageError", "Getting Image failed"); Log.e("ImageError", e.toString()); - result.error("InputImageConverterError", e.toString(), null); + result.error("InputImageConverterError", e.toString(), e); return null; } } else { @@ -39,16 +40,27 @@ public static InputImage getInputImageFromData(Map imageData, Map metaData = (Map) imageData.get("metadata"); assert metaData != null; - inputImage = InputImage.fromByteArray((byte[]) Objects.requireNonNull(imageData.get("bytes")), - Double.valueOf(Objects.requireNonNull(metaData.get("width")).toString()).intValue(), - Double.valueOf(Objects.requireNonNull(metaData.get("height")).toString()).intValue(), - Integer.parseInt(Objects.requireNonNull(metaData.get("rotation")).toString()), - Integer.parseInt(Objects.requireNonNull(metaData.get("image_format")).toString())); - return inputImage; + byte[] data = (byte[]) Objects.requireNonNull(imageData.get("bytes")); + int imageFormat = Integer.parseInt(Objects.requireNonNull(metaData.get("image_format")).toString()); + int rotationDegrees = Integer.parseInt(Objects.requireNonNull(metaData.get("rotation")).toString()); + int width = Double.valueOf(Objects.requireNonNull(metaData.get("width")).toString()).intValue(); + int height = Double.valueOf(Objects.requireNonNull(metaData.get("height")).toString()).intValue(); + if (imageFormat == ImageFormat.NV21 || imageFormat == ImageFormat.YV12) { + return InputImage.fromByteArray( + data, + width, + height, + rotationDegrees, + imageFormat); + } + result.error("InputImageConverterError", "ImageFormat is not supported.", null); + // TODO: Use InputImage.fromMediaImage, which supports more types, e.g. IMAGE_FORMAT_YUV_420_888. + // See https://developers.google.com/android/reference/com/google/mlkit/vision/common/InputImage#fromMediaImage(android.media.Image,%20int) + return null; } catch (Exception e) { Log.e("ImageError", "Getting Image failed"); Log.e("ImageError", e.toString()); - result.error("InputImageConverterError", e.toString(), null); + result.error("InputImageConverterError", e.toString(), e); return null; } } else {