Fix drawing SkAnimatedImages with transparency
Bug: b/74195953
Do not use SkBlendMode::kSrc, which overwrites the pixels that were
already present. Instead, blend normally.
Change-Id: Ie6843c6278212fddddd0ba0ae292fdb5eaf2342e
Reviewed-on: https://skia-review.googlesource.com/112200
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Leon Scroggins <scroggo@google.com>
diff --git a/src/android/SkAnimatedImage.cpp b/src/android/SkAnimatedImage.cpp
index c9fa483..de25f30 100644
--- a/src/android/SkAnimatedImage.cpp
+++ b/src/android/SkAnimatedImage.cpp
@@ -289,7 +289,6 @@
SkAutoCanvasRestore acr(canvas, fPostProcess);
canvas->concat(fMatrix);
SkPaint paint;
- paint.setBlendMode(SkBlendMode::kSrc);
paint.setFilterQuality(kLow_SkFilterQuality);
canvas->drawBitmap(fActiveFrame.fBitmap, 0, 0, &paint);
}
diff --git a/tests/AnimatedImageTest.cpp b/tests/AnimatedImageTest.cpp
index e0a640b..6c7b0e5 100644
--- a/tests/AnimatedImageTest.cpp
+++ b/tests/AnimatedImageTest.cpp
@@ -15,6 +15,7 @@
#include "SkColor.h"
#include "SkData.h"
#include "SkImageInfo.h"
+#include "SkPicture.h"
#include "SkRefCnt.h"
#include "SkSize.h"
#include "SkString.h"
@@ -27,6 +28,50 @@
#include <memory>
#include <vector>
+DEF_TEST(AnimatedImage_scaled, r) {
+ if (GetResourcePath().isEmpty()) {
+ return;
+ }
+
+ const char* file = "images/alphabetAnim.gif";
+ auto data = GetResourceAsData(file);
+ if (!data) {
+ ERRORF(r, "Could not get %s", file);
+ return;
+ }
+
+ auto codec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(data));
+ if (!codec) {
+ ERRORF(r, "Could not create codec for %s", file);
+ return;
+ }
+
+ // Force the drawable follow its special case that requires scaling.
+ auto size = codec->getInfo().dimensions();
+ size.set(size.width() - 5, size.height() - 5);
+ auto rect = SkIRect::MakeSize(size);
+ auto image = SkAnimatedImage::Make(std::move(codec), size, rect, nullptr);
+ if (!image) {
+ ERRORF(r, "Failed to create animated image for %s", file);
+ return;
+ }
+
+ // Clear a bitmap to non-transparent and draw to it. pixels that are transparent
+ // in the image should not replace the original non-transparent color.
+ SkBitmap bm;
+ bm.allocPixels(SkImageInfo::MakeN32Premul(size.width(), size.height()));
+ bm.eraseColor(SK_ColorBLUE);
+ SkCanvas canvas(bm);
+ image->draw(&canvas);
+ for (int i = 0; i < size.width(); ++i)
+ for (int j = 0; j < size.height(); ++j) {
+ if (*bm.getAddr32(i, j) == SK_ColorTRANSPARENT) {
+ ERRORF(r, "Erased color underneath!");
+ return;
+ }
+ }
+}
+
DEF_TEST(AnimatedImage, r) {
if (GetResourcePath().isEmpty()) {
return;