Merge pull request #5599 from radarhere/palette

Updates for ImagePalette channel order
This commit is contained in:
Hugo van Kemenade 2021-08-24 14:52:46 +03:00 committed by GitHub
commit 4c7777c425
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 19 additions and 27 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -856,7 +856,7 @@ def test_palette_save_ImagePalette(tmp_path):
with Image.open(out) as reloaded: with Image.open(out) as reloaded:
im.putpalette(palette) im.putpalette(palette)
assert_image_equal(reloaded, im) assert_image_equal(reloaded.convert("RGB"), im.convert("RGB"))
def test_save_I(tmp_path): def test_save_I(tmp_path):

View File

@ -2,7 +2,7 @@ import pytest
from PIL import Image, ImagePalette from PIL import Image, ImagePalette
from .helper import assert_image_equal, hopper from .helper import assert_image_equal, assert_image_equal_tofile, hopper
def test_putpalette(): def test_putpalette():
@ -36,9 +36,15 @@ def test_putpalette():
def test_imagepalette(): def test_imagepalette():
im = hopper("P") im = hopper("P")
im.putpalette(ImagePalette.negative()) im.putpalette(ImagePalette.negative())
assert_image_equal_tofile(im.convert("RGB"), "Tests/images/palette_negative.png")
im.putpalette(ImagePalette.random()) im.putpalette(ImagePalette.random())
im.putpalette(ImagePalette.sepia()) im.putpalette(ImagePalette.sepia())
assert_image_equal_tofile(im.convert("RGB"), "Tests/images/palette_sepia.png")
im.putpalette(ImagePalette.wedge()) im.putpalette(ImagePalette.wedge())
assert_image_equal_tofile(im.convert("RGB"), "Tests/images/palette_wedge.png")
def test_putpalette_with_alpha_values(): def test_putpalette_with_alpha_values():

View File

@ -9,10 +9,6 @@ represent the color palette of palette mapped images.
.. note:: .. note::
This module was never well-documented. It hasn't changed since 2001,
though, so it's probably safe for you to read the source code and puzzle
out the internals if you need to.
The :py:class:`~PIL.ImagePalette.ImagePalette` class has several methods, The :py:class:`~PIL.ImagePalette.ImagePalette` class has several methods,
but they are all marked as "experimental." Read that as you will. The but they are all marked as "experimental." Read that as you will. The
``[source]`` link is there for a reason. ``[source]`` link is there for a reason.

View File

@ -396,15 +396,7 @@ def _normalize_palette(im, palette, info):
if isinstance(palette, (bytes, bytearray, list)): if isinstance(palette, (bytes, bytearray, list)):
source_palette = bytearray(palette[:768]) source_palette = bytearray(palette[:768])
if isinstance(palette, ImagePalette.ImagePalette): if isinstance(palette, ImagePalette.ImagePalette):
source_palette = bytearray( source_palette = bytearray(palette.palette)
itertools.chain.from_iterable(
zip(
palette.palette[:256],
palette.palette[256:512],
palette.palette[512:768],
)
)
)
if im.mode == "P": if im.mode == "P":
if not source_palette: if not source_palette:

View File

@ -26,12 +26,12 @@ class ImagePalette:
""" """
Color palette for palette mapped images Color palette for palette mapped images
:param mode: The mode to use for the Palette. See: :param mode: The mode to use for the palette. See:
:ref:`concept-modes`. Defaults to "RGB" :ref:`concept-modes`. Defaults to "RGB"
:param palette: An optional palette. If given, it must be a bytearray, :param palette: An optional palette. If given, it must be a bytearray,
an array or a list of ints between 0-255. The list must be aligned an array or a list of ints between 0-255. The list must consist of
by channel (All R values must be contiguous in the list before G all channels for one color followed by the next color (e.g. RGBRGBRGB).
and B values.) Defaults to 0 through 255 per channel. Defaults to an empty palette.
:param size: An optional palette size. If given, an error is raised :param size: An optional palette size. If given, an error is raised
if ``palette`` is not of equal length. if ``palette`` is not of equal length.
""" """
@ -211,9 +211,9 @@ def make_gamma_lut(exp):
def negative(mode="RGB"): def negative(mode="RGB"):
palette = list(range(256)) palette = list(range(256 * len(mode)))
palette.reverse() palette.reverse()
return ImagePalette(mode, palette * len(mode)) return ImagePalette(mode, [i // len(mode) for i in palette])
def random(mode="RGB"): def random(mode="RGB"):
@ -226,15 +226,13 @@ def random(mode="RGB"):
def sepia(white="#fff0c0"): def sepia(white="#fff0c0"):
r, g, b = ImageColor.getrgb(white) bands = [make_linear_lut(0, band) for band in ImageColor.getrgb(white)]
r = make_linear_lut(0, r) return ImagePalette("RGB", [bands[i % 3][i // 3] for i in range(256 * 3)])
g = make_linear_lut(0, g)
b = make_linear_lut(0, b)
return ImagePalette("RGB", r + g + b)
def wedge(mode="RGB"): def wedge(mode="RGB"):
return ImagePalette(mode, list(range(256)) * len(mode)) palette = list(range(256 * len(mode)))
return ImagePalette(mode, [i // len(mode) for i in palette])
def load(filename): def load(filename):