From 1fd2e0eb1bd7a1503f39b3a3b659bf85734ac3db Mon Sep 17 00:00:00 2001 From: Xunkai Zhang Date: Tue, 28 Apr 2020 08:16:54 -0700 Subject: [PATCH] [tfls.image] Add TensorImage.fromBitmap shortcut. PiperOrigin-RevId: 308825884 Change-Id: Ic8939641a45507005f4fa05bbc03d0ba96c8c01c --- .../lite/support/image/TensorImage.java | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/tensorflow/lite/experimental/support/java/src/java/org/tensorflow/lite/support/image/TensorImage.java b/tensorflow/lite/experimental/support/java/src/java/org/tensorflow/lite/support/image/TensorImage.java index 2d57749b7c7..b19ef2e3b62 100644 --- a/tensorflow/lite/experimental/support/java/src/java/org/tensorflow/lite/support/image/TensorImage.java +++ b/tensorflow/lite/experimental/support/java/src/java/org/tensorflow/lite/support/image/TensorImage.java @@ -28,16 +28,16 @@ import org.tensorflow.lite.support.tensorbuffer.TensorBuffer; * TFLite.support library, it's common to convert image objects in variant types to TensorImage at * first. * - *

We are adopting a little bit complex strategy to keep data here. In short, a TensorImage - * object may have 2 potential sources of truth: the real and updated image could be in a Bitmap, or - * a TensorBuffer, or both. It's mainly for performance, avoiding redundant data conversions. + *

At present, only RGB images are supported, and the A channel is always ignored. + * + *

Details of data storage: a {@link TensorImage} object may have 2 potential sources of truth: a + * {@link Bitmap} or a {@link TensorBuffer}. {@link TensorImage} maintains the state and only + * convert one to the other when needed. * *

IMPORTANT: The container doesn't own its data. Callers should not modify data objects those * are passed to {@link ImageContainer#set(Bitmap)} or {@link ImageContainer#set(TensorBuffer)}. * - *

IMPORTANT: All methods are not proved thread-safe. Note: This class still a WIP. Currently, it - * supports only RGB color space in uint8 (0-255). When getting Bitmap, value of A channel is always - * set by 0. + *

IMPORTANT: All methods are not proved thread-safe. * * @see ImageProcessor which is often used for transforming a {@link TensorImage}. */ @@ -79,6 +79,18 @@ public class TensorImage { container = new ImageContainer(dataType); } + /** + * Initializes a {@link TensorImage} object with a {@link Bitmap}. + * + * @see TensorImage#load(Bitmap) for reusing the object when it's expensive to create objects + * frequently, because every call of {@code fromBitmap} creates a new {@link TensorImage}. + */ + public static TensorImage fromBitmap(Bitmap bitmap) { + TensorImage image = new TensorImage(); + image.load(bitmap); + return image; + } + /** * Creates a deep-copy of a given {@link TensorImage} and converts internal tensor data type. * @@ -171,7 +183,7 @@ public class TensorImage { *

Important: It's only a reference. DO NOT MODIFY. We don't create a copy here for performance * concern, but if modification is necessary, please make a copy. * - * @return a reference to a Bitmap representing the image in ARGB_8888 config. A is always 0. + * @return a reference to a Bitmap in ARGB_8888 config. "A" channel is always opaque. * @throws IllegalStateException if the TensorImage never loads data, or if the TensorImage is * holding a float-value image in {@code TensorBuffer}. */