DrawImage doesn't work properly with SKFilterQuality.High

289 views
Skip to first unread message

Maxim Rylov

unread,
Apr 21, 2017, 5:16:46 PM4/21/17
to skia-discuss
Hi there,

In a .NET application using SkiaSharp library (version 1.57), I've found a really strange bug.
When I tried to draw the following image onto a canvas with SKFilterQuality.High, transparent pixels of the source image were replaced with white color. If I use SKFilterQuality.Medium, the image is drawn correctly.



Original image



Output with SKFilterQuality.High


Output with SKFilterQuality.Medium

The source code of my tests can be found in this GitHub repository.


Kind regards,
Max
Auto Generated Inline Image 1
Auto Generated Inline Image 2
Auto Generated Inline Image 3

Hal Canary

unread,
Apr 22, 2017, 4:58:09 PM4/22/17
to skia-discuss
You are unlikely to find anyone on this list who knows about SkiaSharp.  Can you reproduce the bug in C++?


--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss+unsubscribe@googlegroups.com.
To post to this group, send email to skia-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/skia-discuss.
For more options, visit https://groups.google.com/d/optout.

Maxim Rylov

unread,
Apr 23, 2017, 8:37:46 AM4/23/17
to skia-discuss
Hi Hal,


You are unlikely to find anyone on this list who knows about SkiaSharp. 
Last time when I posted about another issue in SkiaSharp in its own Github reposistory, I have been asked to post on this forum.


 Can you reproduce the bug in C++?
Unfortunately, I am not able to do that. I am pretty sure, that since SkiaSharp is just a wrapper around Skia, this bug can be reproduce and in C++.

I have forgotten to mention that I ran my tests on Windows 7 and 10 (x64) machines.



On Saturday, April 22, 2017 at 10:58:09 PM UTC+2, Hal Canary wrote:
You are unlikely to find anyone on this list who knows about SkiaSharp.  Can you reproduce the bug in C++?
On Fri, Apr 21, 2017 at 5:16 PM, 'Maxim Rylov' via skia-discuss <skia-d...@googlegroups.com> wrote:
Hi there,

In a .NET application using SkiaSharp library (version 1.57), I've found a really strange bug.
When I tried to draw the following image onto a canvas with SKFilterQuality.High, transparent pixels of the source image were replaced with white color. If I use SKFilterQuality.Medium, the image is drawn correctly.



Original image



Output with SKFilterQuality.High


Output with SKFilterQuality.Medium

The source code of my tests can be found in this GitHub repository.


Kind regards,
Max

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.

Hal Canary

unread,
Apr 23, 2017, 10:22:12 AM4/23/17
to skia-discuss
The following works correctly for me:

    auto image = SkImage::MakeFromEncoded(SkData::MakeFromFileName("unnamed.png"));    
    auto surface = SkSurface::MakeRasterN32Premul(500, 700);
    surface->getCanvas()->clear(SkColorSetARGB(255, 158, 180, 214));
    SkPaint paint;
    paint.setFilterQuality(kHigh_SkFilterQuality);
    surface->getCanvas()->drawImageRect(image,
           SkRect::MakeXYWH(-259.9664f, -260.4489f, 1221.1876f, 1020.23273), &paint);
    sk_sp<SkData> e(surface->makeImageSnapshot()->encode());
    SkFILEWStream file("output.png");
    file.write(e->data(), e->size());


To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss+unsubscribe@googlegroups.com.

Maxim Rylov

unread,
Apr 26, 2017, 3:28:38 PM4/26/17
to skia-discuss
Hi Hal,

Thanks a lot for checking that. I will try to contact the author of SkiaSharp then.

Matthew Leibowitz

unread,
May 11, 2017, 2:17:14 PM5/11/17
to skia-discuss
Hi Hal,

I think I found out why things were going wonky. When drawing a Unpremul image, the transparency is somehow lost, but Premul works fine.

When decoding the image in the simplest way with SkiaSharp, I use the SkImageInfo provided by SkCodec. 
Upon investigation, the SkImageInfo has an alpha type of Unpremul. When using SkImage::MakeFromEncoded, the resulting image is Premul.
Using this information, I tried using a SkImageInfo with a Premul alpha type when decoding, and now it works as expected.

I tried this with the latest version of skia, and I can reproduce it. 
Also, this only occurs if I specify a draw rectangle that is larger than the actual image, and the filter is set to High: drawImageRect(image, {0,0,width*2,height*2}, paint)

Is this anything useful?

Matthew Leibowitz

unread,
May 11, 2017, 2:29:19 PM5/11/17
to skia-discuss
When I decode the image, I am using the SkImageInfo fromSkCodec. The alpha type is often (if not always) Unpremul. Is this a valid type to decode into, or should I always try and use Premul? Are there advantages or disadvantages to either?


On Sunday, April 23, 2017 at 9:22:12 AM UTC-5, Hal Canary wrote:

Matt Sarett

unread,
May 11, 2017, 2:43:18 PM5/11/17
to skia-d...@googlegroups.com
For the encoded image types that SkCodec supports, the alpha type of the encoded data is always kOpaque or kUnpremul.  If the alpha type is kUnpremul, SkCodec will support decoding to kUnpremul or kPremul (meaning that the codec can optionally perform an additional transformation to convert to kPremul).

Skia only supports drawing premultiplied bitmaps/images.  However, asking for kPremul is tricky, given that premultiplication is closely tied to blending, and Skia supports multiple premultiplcation/blending strategies.  See SkCodec::Options::SkTransferFunctionBehavior for more details (https://skia.googlesource.com/skia/+/master/include/core/SkColorSpace.h#171).

Why not just use the following pattern (pseudocode)?
image = SkImage::MakeFromEncoded(<encoded data>);
canvas->draw(image);


To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss+unsubscribe@googlegroups.com.

Matthew Leibowitz

unread,
May 11, 2017, 2:47:47 PM5/11/17
to skia-discuss
I can use that, and I will recommend that going forward, but I was wondering why the transparency is lost when drawing a Unpremul image. 

Matthew Leibowitz

unread,
May 11, 2017, 2:49:15 PM5/11/17
to skia-discuss
Also, the only way I can see for decoding individual GIF frames is to use SkCodec...


On Thursday, May 11, 2017 at 1:43:18 PM UTC-5, Matt Sarett wrote:

Matt Sarett

unread,
May 11, 2017, 2:54:16 PM5/11/17
to skia-d...@googlegroups.com
"I can use that, and I will recommend that going forward, but I was wondering why the transparency is lost when drawing a Unpremul image. "

My *guess* is that, because we don't support drawing kUnpremul, somewhere we are doing this:

if (isPremul) {
    // Draw premul
} else {
    // Assume opaque
}

"Also, the only way I can see for decoding individual GIF frames is to use SkCodec..."

This is true, and a good use of SkCodec.  FWIW, there may be future work on a higher level API.  Also, GIF pixels are always opaque or fully transparent, so there should be no issue decoding to kPremul in this case.

To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss+unsubscribe@googlegroups.com.

Matthew Leibowitz

unread,
May 11, 2017, 3:48:01 PM5/11/17
to skia-discuss
Thanks for the info and help.

Do you know of any cases where loading a bitmap as premul will case issues? Of course, if it is opaque then we can skip that, but if it is unpremul.

I am going to add the SkImage method, but I have existing functionality that I think I need to change to ensure that we always do premul. 

Matt Sarett

unread,
May 11, 2017, 4:04:55 PM5/11/17
to skia-d...@googlegroups.com
No problem!

If you are drawing with legacy Skia (the SkColorSpace on your SkSurface/SkCanvas is nullptr), you'll want to specify SkCodec::Options::SkTransferFunctionBehavior::kIgnore.

If you are drawing with color correct Skia (the SkColorSpace on your SkSurface/SkCanvas is non-nullptr), you'll want to specify SkCodec::Options::SkTransferFunctionBehavior::kRespect.

To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages