summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Leon Scroggins III <scroggo@google.com> 2018-12-17 10:40:07 -0500
committer Leon Scroggins III <scroggo@google.com> 2019-01-15 12:16:19 -0500
commit4c4259b33972300f98d77a19d80d9971b521c1b9 (patch)
tree03bd2d2b4cc346777a042b50299f55824fff249d
parent5ca575ae71493aedfbd93da032692ad5a1d50f27 (diff)
Add Bitmap#eraseColor(@ColorLong) + helpers
Bug: 120904891 Test: I162451ebf807f3a8a44679e5c10406468c922500 - Add Bitmap#eraseColor(@ColorLong). This allows erasing in ColorSpaces besides SRGB. New API is hidden pending API-council approval. It is @TestApi so it can be used by the new tests. - Rewrite Bitmap#erase(@ColorInt)'s internals. The ColorInt should be treated as an SRGB color. The old code (deep in SkPixmap::erase) treated the color as being in the SkColorSpace of the SkBitmap. - Update getNativeColorSpace to return immediately when it throws. Existing callers should never throw anyway, since they do their own checks (and throws) in Java before reaching this method. But relying on this method to properly return simplifies the new callers. Change-Id: I1b736934ce1b8294c827bb61c2a363207569da4f
-rw-r--r--api/test-current.txt4
-rwxr-xr-xcore/jni/android/graphics/Bitmap.cpp26
-rw-r--r--core/jni/android/graphics/Graphics.cpp2
-rw-r--r--graphics/java/android/graphics/Bitmap.java28
4 files changed, 59 insertions, 1 deletions
diff --git a/api/test-current.txt b/api/test-current.txt
index 957f957d21a3..928aa08591e1 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -494,6 +494,10 @@ package android.database.sqlite {
package android.graphics {
+ public final class Bitmap implements android.os.Parcelable {
+ method public void eraseColor(long);
+ }
+
public final class ImageDecoder implements java.lang.AutoCloseable {
method public static android.graphics.ImageDecoder.Source createSource(android.content.res.Resources, java.io.InputStream, int);
}
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index eb7338a7ce58..f188a0fcd87d 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -568,11 +568,34 @@ static jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle,
return SkEncodeImage(strm.get(), skbitmap, fm, quality) ? JNI_TRUE : JNI_FALSE;
}
+static inline void bitmapErase(SkBitmap bitmap, const SkColor4f& color,
+ const sk_sp<SkColorSpace>& colorSpace) {
+ SkPaint p;
+ p.setColor4f(color, colorSpace.get());
+ p.setBlendMode(SkBlendMode::kSrc);
+ SkCanvas canvas(bitmap);
+ canvas.drawPaint(p);
+}
+
static void Bitmap_erase(JNIEnv* env, jobject, jlong bitmapHandle, jint color) {
LocalScopedBitmap bitmap(bitmapHandle);
SkBitmap skBitmap;
bitmap->getSkBitmap(&skBitmap);
- skBitmap.eraseColor(color);
+ bitmapErase(skBitmap, SkColor4f::FromColor(color), SkColorSpace::MakeSRGB());
+}
+
+static void Bitmap_eraseLong(JNIEnv* env, jobject, jlong bitmapHandle, jobject jColorSpace,
+ jfloat r, jfloat g, jfloat b, jfloat a) {
+ sk_sp<SkColorSpace> cs = GraphicsJNI::getNativeColorSpace(env, jColorSpace);
+ if (GraphicsJNI::hasException(env)) {
+ return;
+ }
+
+ LocalScopedBitmap bitmap(bitmapHandle);
+ SkBitmap skBitmap;
+ bitmap->getSkBitmap(&skBitmap);
+ SkColor4f color = SkColor4f{r, g, b, a};
+ bitmapErase(skBitmap, color, cs);
}
static jint Bitmap_rowBytes(JNIEnv* env, jobject, jlong bitmapHandle) {
@@ -1183,6 +1206,7 @@ static const JNINativeMethod gBitmapMethods[] = {
{ "nativeCompress", "(JIILjava/io/OutputStream;[B)Z",
(void*)Bitmap_compress },
{ "nativeErase", "(JI)V", (void*)Bitmap_erase },
+ { "nativeErase", "(JLandroid/graphics/ColorSpace;FFFF)V", (void*)Bitmap_eraseLong },
{ "nativeRowBytes", "(J)I", (void*)Bitmap_rowBytes },
{ "nativeConfig", "(J)I", (void*)Bitmap_config },
{ "nativeHasAlpha", "(J)Z", (void*)Bitmap_hasAlpha },
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 67d0c8aced61..548a249d9472 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -456,12 +456,14 @@ sk_sp<SkColorSpace> GraphicsJNI::getNativeColorSpace(JNIEnv* env, jobject colorS
if (colorSpace == nullptr) return nullptr;
if (!env->IsInstanceOf(colorSpace, gColorSpaceRGB_class)) {
doThrowIAE(env, "The color space must be an RGB color space");
+ return nullptr;
}
jobject transferParams = env->CallObjectMethod(colorSpace,
gColorSpaceRGB_getTransferParametersMethodID);
if (transferParams == nullptr) {
doThrowIAE(env, "The color space must use an ICC parametric transfer function");
+ return nullptr;
}
jfloatArray illuminantD50 = (jfloatArray) env->GetStaticObjectField(gColorSpace_class,
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 790b37eec4c5..30f0bfa68b4a 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -18,9 +18,11 @@ package android.graphics;
import android.annotation.CheckResult;
import android.annotation.ColorInt;
+import android.annotation.ColorLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.annotation.WorkerThread;
import android.content.res.ResourcesImpl;
@@ -1780,6 +1782,30 @@ public final class Bitmap implements Parcelable {
}
/**
+ * Fills the bitmap's pixels with the specified {@link Color}.
+ *
+ * @throws IllegalStateException if the bitmap is not mutable.
+ * @throws IllegalArgumentException if the color space encoded in the long
+ * is invalid or unknown.
+ *
+ * @hide pending API approval
+ */
+ @TestApi
+ public void eraseColor(@ColorLong long c) {
+ checkRecycled("Can't erase a recycled bitmap");
+ if (!isMutable()) {
+ throw new IllegalStateException("cannot erase immutable bitmaps");
+ }
+
+ ColorSpace cs = Color.colorSpace(c);
+ float r = Color.red(c);
+ float g = Color.green(c);
+ float b = Color.blue(c);
+ float a = Color.alpha(c);
+ nativeErase(mNativePtr, cs, r, g, b, a);
+ }
+
+ /**
* 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). The returned color is a non-premultiplied ARGB value in
@@ -2123,6 +2149,8 @@ public final class Bitmap implements Parcelable {
int quality, OutputStream stream,
byte[] tempStorage);
private static native void nativeErase(long nativeBitmap, int color);
+ private static native void nativeErase(long nativeBitmap, ColorSpace cs,
+ float r, float g, float b, float a);
private static native int nativeRowBytes(long nativeBitmap);
private static native int nativeConfig(long nativeBitmap);