Allow putpalette to accept 1024 integers to include alpha values

This commit is contained in:
Andrew Murray 2020-12-12 14:12:30 +11:00
parent 4ed79ea79c
commit a666c91e10
2 changed files with 37 additions and 10 deletions

View File

@ -1,8 +1,8 @@
import pytest import pytest
from PIL import ImagePalette from PIL import Image, ImagePalette
from .helper import hopper from .helper import assert_image_equal, hopper
def test_putpalette(): def test_putpalette():
@ -39,3 +39,20 @@ def test_imagepalette():
im.putpalette(ImagePalette.random()) im.putpalette(ImagePalette.random())
im.putpalette(ImagePalette.sepia()) im.putpalette(ImagePalette.sepia())
im.putpalette(ImagePalette.wedge()) im.putpalette(ImagePalette.wedge())
def test_putpalette_with_alpha_values():
with Image.open("Tests/images/transparent.gif") as im:
expected = im.convert("RGBA")
palette = im.getpalette()
transparency = im.info.pop("transparency")
palette_with_alpha_values = []
for i in range(256):
color = palette[i * 3 : i * 3 + 3]
alpha = 0 if i == transparency else 255
palette_with_alpha_values += color + [alpha]
im.putpalette(palette_with_alpha_values, "RGBA")
assert_image_equal(im.convert("RGBA"), expected)

View File

@ -815,9 +815,15 @@ class Image:
""" """
if self.im and self.palette and self.palette.dirty: if self.im and self.palette and self.palette.dirty:
# realize palette # realize palette
self.im.putpalette(*self.palette.getdata()) mode, arr = self.palette.getdata()
if mode == "RGBA":
mode = "RGB"
self.info["transparency"] = arr[3::4]
arr = bytes(
value for (index, value) in enumerate(arr) if index % 4 != 3
)
self.im.putpalette(mode, arr)
self.palette.dirty = 0 self.palette.dirty = 0
self.palette.mode = "RGB"
self.palette.rawmode = None self.palette.rawmode = None
if "transparency" in self.info: if "transparency" in self.info:
if isinstance(self.info["transparency"], int): if isinstance(self.info["transparency"], int):
@ -825,6 +831,8 @@ class Image:
else: else:
self.im.putpalettealphas(self.info["transparency"]) self.im.putpalettealphas(self.info["transparency"])
self.palette.mode = "RGBA" self.palette.mode = "RGBA"
else:
self.palette.mode = "RGB"
if self.im: if self.im:
if cffi and USE_CFFI_ACCESS: if cffi and USE_CFFI_ACCESS:
@ -1672,12 +1680,14 @@ class Image:
def putpalette(self, data, rawmode="RGB"): def putpalette(self, data, rawmode="RGB"):
""" """
Attaches a palette to this image. The image must be a "P", Attaches a palette to this image. The image must be a "P", "PA", "L"
"PA", "L" or "LA" image, and the palette sequence must contain or "LA" image.
768 integer values, where each group of three values represent
the red, green, and blue values for the corresponding pixel The palette sequence must contain either 768 integer values, or 1024
index. Instead of an integer sequence, you can use an 8-bit integer values if alpha is included. Each group of values represents
string. the red, green, blue (and alpha if included) values for the
corresponding pixel index. Instead of an integer sequence, you can use
an 8-bit string.
:param data: A palette sequence (either a list or a string). :param data: A palette sequence (either a list or a string).
:param rawmode: The raw mode of the palette. :param rawmode: The raw mode of the palette.