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>
This commit is contained in:
Leon Scroggins III 2018-03-05 14:19:40 -05:00 committed by Skia Commit-Bot
parent bd6525304d
commit 2f8622029d
2 changed files with 45 additions and 1 deletions

View File

@ -289,7 +289,6 @@ void SkAnimatedImage::onDraw(SkCanvas* canvas) {
SkAutoCanvasRestore acr(canvas, fPostProcess);
canvas->concat(fMatrix);
SkPaint paint;
paint.setBlendMode(SkBlendMode::kSrc);
paint.setFilterQuality(kLow_SkFilterQuality);
canvas->drawBitmap(fActiveFrame.fBitmap, 0, 0, &paint);
}

View File

@ -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;