Skia 越野车颜色混合

Skia buggy color blending

我正在使用带有 Open GL 后端的 Skia m62 并在渲染 png 文件时出现故障。

要创建 SkBitmap 我正在使用以下代码:

const auto codec = SkCodec::MakeFromStream(SkStream::MakeFromFile("test.png"));
const SkImageInfo imageInfo = codec->getInfo().makeColorType(kN32_SkColorType);
SkBitmap bm;
bm.allocPixels(imageInfo);
codec->getPixels(imageInfo, bm.getPixels(), bm.rowBytes());

其余代码略有修改(无法找到 gl/GrGLUtil.h header)在 Skia 资源中找到的示例:https://github.com/google/skia/blob/master/example/SkiaSDLExample.cpp

库是用参数构建的:skia_use_freetype=true skia_use_system_freetype2=false skia_use_libpng=true skia_use_system_libpng=false skia_use_expat=false skia_use_icu=false skia_use_libjpeg_turbo=false skia_use_libwebp=false skia_use_piex=false skia_use_sfntly=false skia_use_zlib=true skia_use_system_zlib=false is_official_build=true target_os="mac" target_cpu="x86_64"

这是说明问题的 FULL EXAMPLE on GitHub。它包含在 Mac OS x86_64.

上观察和完整设置为 运行 的 png

UPD:在 Skia 跟踪器中提交了一个错误:https://bugs.chromium.org/p/skia/issues/detail?id=7361

我将引用 Skia 的 bugtracker 的答案:

Skia's GPU backend doesn't support drawing unpremultiplied images, but that is the natural state of most encoded images, including all .pngs. What you're seeing is an unpremultiplied bitmap being drawn as if it were a premultiplied bitmap. Pretty isn't it?

There are a couple easy ways to fix this. The simplest way to adapt the code you have there is to make sure to ask SkCodec for premultiplied output, e.g.

const SkImageInfo imageInfo = codec->getInfo().makeColorType(kN32_SkColorType) .makeAlphaType(kPremul_SkAlphaType);

Or, you can use this simpler way to decode and draw:

sk_sp img = SkImage::MakeFromEncoded(SkData::MakeFromFileName("test.png")); ... canvas->drawImage(img, ...);

That way lets SkImage::MakeFromEncoded() make all the choices about format for you.

这解决了问题。