diff options
| -rw-r--r-- | api/test-current.txt | 1 | ||||
| -rwxr-xr-x | core/jni/android/graphics/Bitmap.cpp | 14 | ||||
| -rw-r--r-- | graphics/java/android/graphics/Bitmap.java | 43 |
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); |