mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 10:26:19 +03:00
Merge pull request #5599 from radarhere/palette
Updates for ImagePalette channel order
This commit is contained in:
commit
4c7777c425
BIN
Tests/images/palette_negative.png
Normal file
BIN
Tests/images/palette_negative.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
Tests/images/palette_sepia.png
Normal file
BIN
Tests/images/palette_sepia.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
Tests/images/palette_wedge.png
Normal file
BIN
Tests/images/palette_wedge.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
|
@ -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):
|
||||||
|
|
|
@ -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():
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user