summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/test-current.txt1
-rwxr-xr-xcore/jni/android/graphics/Bitmap.cpp14
-rw-r--r--graphics/java/android/graphics/Bitmap.java43
3 files changed, 58 insertions, 0 deletions
diff --git a/api/test-current.txt b/api/test-current.txt
index e9f340b1a1e2..4fc175742e80 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -520,6 +520,7 @@ package android.graphics {
public final class Bitmap implements android.os.Parcelable {
method public void eraseColor(@ColorLong long);
+ method public android.graphics.Color getColor(int, int);
method public void setColorSpace(@NonNull android.graphics.ColorSpace);
}
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index c74797b60e69..d215f965b3c2 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -986,6 +986,19 @@ static jint Bitmap_getPixel(JNIEnv* env, jobject, jlong bitmapHandle,
return static_cast<jint>(dst);
}
+static jlong Bitmap_getColor(JNIEnv* env, jobject, jlong bitmapHandle,
+ jint x, jint y) {
+ SkBitmap bitmap;
+ reinterpret_cast<BitmapWrapper*>(bitmapHandle)->getSkBitmap(&bitmap);
+
+ SkImageInfo dstInfo = SkImageInfo::Make(
+ 1, 1, kRGBA_F16_SkColorType, kUnpremul_SkAlphaType, bitmap.refColorSpace());
+
+ uint64_t dst;
+ bitmap.readPixels(dstInfo, &dst, dstInfo.minRowBytes(), x, y);
+ return static_cast<jlong>(dst);
+}
+
static void Bitmap_getPixels(JNIEnv* env, jobject, jlong bitmapHandle,
jintArray pixelArray, jint offset, jint stride,
jint x, jint y, jint width, jint height) {
@@ -1231,6 +1244,7 @@ static const JNINativeMethod gBitmapMethods[] = {
(void*)Bitmap_extractAlpha },
{ "nativeGenerationId", "(J)I", (void*)Bitmap_getGenerationId },
{ "nativeGetPixel", "(JII)I", (void*)Bitmap_getPixel },
+ { "nativeGetColor", "(JII)J", (void*)Bitmap_getColor },
{ "nativeGetPixels", "(J[IIIIIII)V", (void*)Bitmap_getPixels },
{ "nativeSetPixel", "(JIII)V", (void*)Bitmap_setPixel },
{ "nativeSetPixels", "(J[IIIIIII)V", (void*)Bitmap_setPixels },
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index f0e236168858..97cb2ec2b4f7 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -31,6 +31,7 @@ import android.os.Parcelable;
import android.os.StrictMode;
import android.os.Trace;
import android.util.DisplayMetrics;
+import android.util.Half;
import android.util.Log;
import android.view.ThreadedRenderer;
@@ -1848,6 +1849,47 @@ public final class Bitmap implements Parcelable {
return nativeGetPixel(mNativePtr, x, y);
}
+ private static float clamp(float value, @NonNull ColorSpace cs, int index) {
+ return Math.max(Math.min(value, cs.getMaxValue(index)), cs.getMinValue(index));
+ }
+
+ /**
+ * Returns the {@link Color} at the specified location. Throws an exception
+ * if x or y are out of bounds (negative or >= to the width or height
+ * respectively).
+ *
+ * @param x The x coordinate (0...width-1) of the pixel to return
+ * @param y The y coordinate (0...height-1) of the pixel to return
+ * @return The {@link Color} at the specified coordinate
+ * @throws IllegalArgumentException if x, y exceed the bitmap's bounds
+ * @throws IllegalStateException if the bitmap's config is {@link Config#HARDWARE}
+ *
+ * @hide pending API approval
+ */
+ @TestApi
+ public Color getColor(int x, int y) {
+ checkRecycled("Can't call getColor() on a recycled bitmap");
+ checkHardware("unable to getColor(), "
+ + "pixel access is not supported on Config#HARDWARE bitmaps");
+ checkPixelAccess(x, y);
+
+ final ColorSpace cs = getColorSpace();
+ if (cs.equals(ColorSpace.get(ColorSpace.Named.SRGB))) {
+ return Color.valueOf(nativeGetPixel(mNativePtr, x, y));
+ }
+ // The returned value is in kRGBA_F16_SkColorType, which is packed as
+ // four half-floats, r,g,b,a.
+ long rgba = nativeGetColor(mNativePtr, x, y);
+ float r = Half.toFloat((short) ((rgba >> 0) & 0xffff));
+ float g = Half.toFloat((short) ((rgba >> 16) & 0xffff));
+ float b = Half.toFloat((short) ((rgba >> 32) & 0xffff));
+ float a = Half.toFloat((short) ((rgba >> 48) & 0xffff));
+
+ // Skia may draw outside of the numerical range of the colorSpace.
+ // Clamp to get an expected value.
+ return Color.valueOf(clamp(r, cs, 0), clamp(g, cs, 1), clamp(b, cs, 2), a, cs);
+ }
+
/**
* Returns in pixels[] a copy of the data in the bitmap. Each value is
* a packed int representing a {@link Color}. The stride parameter allows
@@ -2176,6 +2218,7 @@ public final class Bitmap implements Parcelable {
private static native boolean nativeIsConfigF16(long nativeBitmap);
private static native int nativeGetPixel(long nativeBitmap, int x, int y);
+ private static native long nativeGetColor(long nativeBitmap, int x, int y);
private static native void nativeGetPixels(long nativeBitmap, int[] pixels,
int offset, int stride, int x, int y,
int width, int height);