skia-python icon indicating copy to clipboard operation
skia-python copied to clipboard

Image.toarray change rgb to bgr on the Linux

Open Polyisoprene opened this issue 2 years ago • 11 comments

Describe the bug On Linux platform use Image.toarray convert image to array ,then use Image.fromarray convert array to image, R and B chennel of the image will switch

To Reproduce Steps to reproduce the behavior:

import httpx
import skia
url = "https://pic3.zhimg.com/v2-2f57af939aef71f510c35928600d79f2_b.jpg"
response = httpx.get(url)
img1 = skia.Image.MakeFromEncoded(response.content)
img1.save("1.png")

img2 = skia.Image.fromarray(img1.toarray())
img2.save("2.png")

Expected behavior R chennel and B chennel will not switch

Desktop (please complete the following information):

  • OS: 22.04.1-Ubuntu
  • Python: 3.10.6
  • skia-python version: 87.5

Additional context Add any other context about the problem here.

Polyisoprene avatar Jun 10 '23 03:06 Polyisoprene

This problem can be solved by passing the "colorType=kia. ColorType. kRGBA_8888_ColorType" parameter when calling toarray

Polyisoprene avatar Jun 10 '23 08:06 Polyisoprene

that's interesting. I just encounted a somewhat similar issue - pretty sure internally skia does kN32_8888 by default. FreeType internally does kBGRA actually, so I have to specify kBGRA to render directly from Skia into a freetype bitmap based memory canvas.

You are basically saying that conversion to/from, one of them is not N32.

HinTak avatar Jul 12 '23 08:07 HinTak

It is actually documented in one of skin's design document that libjpeg and libpng does RGBA and platform neutral, while skia's internal image format is platform dependent, and on intel/small-endian, it is happens to be BGRA . There are different way of getting at it, and some will invoke auto-swap, some won't. So this behaviour is apparently documented.

I found something similar in my situation. I have a buffer maintained by freetype and I wanted skia to fill it. The default doesn't work, and I have to explicitly tell skia that freetype wants BGRA and so please do it as such.

I was doing a SkBitmap canvas with a freetype buffer backing and just ask Skia use the SkBitmap as a Canvas. I guess in my case, because jpeg/png buffers are RGBA, so SkBitmap probably has a default of being RGBA.

HinTak avatar Jul 14 '23 04:07 HinTak

@kyamagu Hmm, looking at this again, why does toarray() and fromarray() have different defaults? fromarray has a default of py::arg("colorType") = kN32_SkColorType, while toarray has py::arg("colorType") = kUnknown_SkColorType. I think Unknown probably will end up being N32 anyway, but somehow obviously hasn't happened. Assuming the code honours those colortypes correctly.

HinTak avatar Aug 19 '23 17:08 HinTak

@HinTak Don't remember why they are different. As kN32_SkColorType seems to exist only for historical reasons, all defaults should be kUnknown_SkColorType.

kyamagu avatar Aug 21 '23 00:08 kyamagu

Hmm, this seems to relate to #250 .

HinTak avatar Jun 28 '24 23:06 HinTak