PNG图像使用Python Pillow的frombytes方法变成黑色。如何保持颜色?

huangapple go评论74阅读模式
英文:

PNG image frombytes turns black using Python Pillow. How to keep colors?

问题

我想旋转这张图片。

PNG图像使用Python Pillow的frombytes方法变成黑色。如何保持颜色?

我将其作为字节存储:

img = Image.open(image_path)
img.tobytes()

但当我解码它时:

image = Image.frombytes('P', (width, height), image_data)

我得到了一个黑色的正方形。

如何从字节中读取图像并保持颜色?这发生在PNG图像上。

我已经尝试了将图像转换为白色背景上的原始图像轮廓,但几乎不可见:

image = Image.frombytes('P', (width, height), image_data).convert('L')

我正在使用Pillow。我愿意使用任何方法。

英文:

I want to rotate this image.

PNG图像使用Python Pillow的frombytes方法变成黑色。如何保持颜色?

I have it as bytes with:

img = Image.open(image_path)
img.tobytes()

But when I decode it:

image = Image.frombytes('P', (width, height), image_data)

I get a black square.

How can I read the image from bytes and keep the colors? This is happening for PNG images.

The farthest I've got is getting a black background with a barely noticeable shape of the original image in white.
With

image = Image.frombytes('P', (width, height), image_data).convert('L')

I'm using Pillow. I'm open to use anything.

答案1

得分: 1

根据 https://github.com/python-pillow/Pillow/issues/6788,这就是图像变黑的原因:

P 模式的思想是有一个最多包含 256 种颜色的调色板,图像中的每个像素都是这些颜色中的一个。tobytes() 只会写出图像像素的索引,而不包含调色板信息。因此,当将这些索引转换回图像时,没有调色板来告诉它每个像素的颜色,所以图像会变成黑色。

该问题列出了几种替代方案:

  • 您可以单独保存调色板,然后在最后应用它到新图像上。
  • 您可以将图像从 P 模式转换为 RGB 或 RGBA。
  • 您可以将图像以特定的图像格式保存(例如 PNG),然后从该格式加载图像。

对我来说,第二个选项似乎是最简单的,因此让我们实现它:

image_path = "aJpWQ.png"
img = Image.open(image_path)

width, height = img.size
converted = img.convert("RGBA")
image_data = converted.tobytes()

# 在这里插入转换操作

image = Image.frombytes('RGBA', (width, height), image_data)
英文:

According to https://github.com/python-pillow/Pillow/issues/6788, this is why the image becomes black:

> The idea of P mode is that there is a palette of up to 256 colors, and each pixel in the image is one of those colors. tobytes() is only writing out the indexes of the image pixels, and not the palette. So the image becomes black because when it converts those indexes back to an image, there is no palette to tell it what color each pixel is.

The issue lists several alternatives:

> - You could save the palette separately, and then apply it to the new image at the end.
> - You could convert the image from P to RGB, or RGBA.
> - You could save the image in a particular image format (PNG for example), and then load the image back from that.

To me, the 2nd option looks like the simplest, so let's implement that:

image_path = "aJpWQ.png"
img = Image.open(image_path)

width, height = img.size
converted = img.convert("RGBA")
image_data = converted.tobytes()

# insert transformations here

image = Image.frombytes('RGBA', (width, height), image_data)

huangapple
  • 本文由 发表于 2023年7月14日 08:07:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76683954.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定