mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-06-30 18:03:07 +03:00
Merge pull request #7420 from radarhere/transparency
This commit is contained in:
commit
8cb1e29491
|
@ -235,3 +235,13 @@ class TestFileWebp:
|
||||||
with Image.open(out_webp) as reloaded:
|
with Image.open(out_webp) as reloaded:
|
||||||
reloaded.load()
|
reloaded.load()
|
||||||
assert reloaded.info["duration"] == 1000
|
assert reloaded.info["duration"] == 1000
|
||||||
|
|
||||||
|
def test_roundtrip_rgba_palette(self, tmp_path):
|
||||||
|
temp_file = str(tmp_path / "temp.webp")
|
||||||
|
im = Image.new("RGBA", (1, 1)).convert("P")
|
||||||
|
assert im.mode == "P"
|
||||||
|
assert im.palette.mode == "RGBA"
|
||||||
|
im.save(temp_file)
|
||||||
|
|
||||||
|
with Image.open(temp_file) as im:
|
||||||
|
assert im.getpixel((0, 0)) == (0, 0, 0, 0)
|
||||||
|
|
|
@ -906,6 +906,31 @@ class TestImage:
|
||||||
im = Image.new("RGB", size)
|
im = Image.new("RGB", size)
|
||||||
assert im.tobytes() == b""
|
assert im.tobytes() == b""
|
||||||
|
|
||||||
|
def test_has_transparency_data(self):
|
||||||
|
for mode in ("1", "L", "P", "RGB"):
|
||||||
|
im = Image.new(mode, (1, 1))
|
||||||
|
assert not im.has_transparency_data
|
||||||
|
|
||||||
|
for mode in ("LA", "La", "PA", "RGBA", "RGBa"):
|
||||||
|
im = Image.new(mode, (1, 1))
|
||||||
|
assert im.has_transparency_data
|
||||||
|
|
||||||
|
# P mode with "transparency" info
|
||||||
|
with Image.open("Tests/images/first_frame_transparency.gif") as im:
|
||||||
|
assert "transparency" in im.info
|
||||||
|
assert im.has_transparency_data
|
||||||
|
|
||||||
|
# RGB mode with "transparency" info
|
||||||
|
with Image.open("Tests/images/rgb_trns.png") as im:
|
||||||
|
assert "transparency" in im.info
|
||||||
|
assert im.has_transparency_data
|
||||||
|
|
||||||
|
# P mode with RGBA palette
|
||||||
|
im = Image.new("RGBA", (1, 1)).convert("P")
|
||||||
|
assert im.mode == "P"
|
||||||
|
assert im.palette.mode == "RGBA"
|
||||||
|
assert im.has_transparency_data
|
||||||
|
|
||||||
def test_apply_transparency(self):
|
def test_apply_transparency(self):
|
||||||
im = Image.new("P", (1, 1))
|
im = Image.new("P", (1, 1))
|
||||||
im.putpalette((0, 0, 0, 1, 1, 1))
|
im.putpalette((0, 0, 0, 1, 1, 1))
|
||||||
|
|
|
@ -351,6 +351,8 @@ Instances of the :py:class:`Image` class have the following attributes:
|
||||||
|
|
||||||
.. seealso:: :attr:`~Image.is_animated`, :func:`~Image.seek` and :func:`~Image.tell`
|
.. seealso:: :attr:`~Image.is_animated`, :func:`~Image.seek` and :func:`~Image.tell`
|
||||||
|
|
||||||
|
.. autoattribute:: PIL.Image.Image.has_transparency_data
|
||||||
|
|
||||||
Classes
|
Classes
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,16 @@ TODO
|
||||||
API Additions
|
API Additions
|
||||||
=============
|
=============
|
||||||
|
|
||||||
TODO
|
has_transparency_data
|
||||||
^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
TODO
|
Images now have :py:attr:`~PIL.Image.Image.has_transparency_data` to indicate
|
||||||
|
whether the image has transparency data, whether in the form of an alpha
|
||||||
|
channel, a palette with an alpha channel, or a "transparency" key in the
|
||||||
|
:py:attr:`~PIL.Image.Image.info` dictionary.
|
||||||
|
|
||||||
|
Even if this attribute is true, the image might still appear solid, if all of
|
||||||
|
the values shown within are opaque.
|
||||||
|
|
||||||
Security
|
Security
|
||||||
========
|
========
|
||||||
|
|
|
@ -915,7 +915,7 @@ class Image:
|
||||||
|
|
||||||
self.load()
|
self.load()
|
||||||
|
|
||||||
has_transparency = self.info.get("transparency") is not None
|
has_transparency = "transparency" in self.info
|
||||||
if not mode and self.mode == "P":
|
if not mode and self.mode == "P":
|
||||||
# determine default mode
|
# determine default mode
|
||||||
if self.palette:
|
if self.palette:
|
||||||
|
@ -1531,6 +1531,24 @@ class Image:
|
||||||
rawmode = mode
|
rawmode = mode
|
||||||
return list(self.im.getpalette(mode, rawmode))
|
return list(self.im.getpalette(mode, rawmode))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def has_transparency_data(self) -> bool:
|
||||||
|
"""
|
||||||
|
Determine if an image has transparency data, whether in the form of an
|
||||||
|
alpha channel, a palette with an alpha channel, or a "transparency" key
|
||||||
|
in the info dictionary.
|
||||||
|
|
||||||
|
Note the image might still appear solid, if all of the values shown
|
||||||
|
within are opaque.
|
||||||
|
|
||||||
|
:returns: A boolean.
|
||||||
|
"""
|
||||||
|
return (
|
||||||
|
self.mode in ("LA", "La", "PA", "RGBA", "RGBa")
|
||||||
|
or (self.mode == "P" and self.palette.mode.endswith("A"))
|
||||||
|
or "transparency" in self.info
|
||||||
|
)
|
||||||
|
|
||||||
def apply_transparency(self):
|
def apply_transparency(self):
|
||||||
"""
|
"""
|
||||||
If a P mode image has a "transparency" key in the info dictionary,
|
If a P mode image has a "transparency" key in the info dictionary,
|
||||||
|
|
|
@ -330,12 +330,7 @@ def _save(im, fp, filename):
|
||||||
exact = 1 if im.encoderinfo.get("exact") else 0
|
exact = 1 if im.encoderinfo.get("exact") else 0
|
||||||
|
|
||||||
if im.mode not in _VALID_WEBP_LEGACY_MODES:
|
if im.mode not in _VALID_WEBP_LEGACY_MODES:
|
||||||
alpha = (
|
im = im.convert("RGBA" if im.has_transparency_data else "RGB")
|
||||||
"A" in im.mode
|
|
||||||
or "a" in im.mode
|
|
||||||
or (im.mode == "P" and "transparency" in im.info)
|
|
||||||
)
|
|
||||||
im = im.convert("RGBA" if alpha else "RGB")
|
|
||||||
|
|
||||||
data = _webp.WebPEncode(
|
data = _webp.WebPEncode(
|
||||||
im.tobytes(),
|
im.tobytes(),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user