diff --git a/Tests/test_image.py b/Tests/test_image.py index 7df1916ef..487035a3e 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -906,6 +906,31 @@ class TestImage: im = Image.new("RGB", size) 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): im = Image.new("P", (1, 1)) im.putpalette((0, 0, 0, 1, 1, 1)) diff --git a/docs/reference/Image.rst b/docs/reference/Image.rst index 66e6b2a0c..ae8f923cb 100644 --- a/docs/reference/Image.rst +++ b/docs/reference/Image.rst @@ -195,6 +195,7 @@ This helps to get the bounding box coordinates of the input image:: .. automethod:: PIL.Image.Image.getpalette .. automethod:: PIL.Image.Image.getpixel .. automethod:: PIL.Image.Image.getprojection +.. automethod:: PIL.Image.Image.has_transparency_data .. automethod:: PIL.Image.Image.histogram .. automethod:: PIL.Image.Image.paste .. automethod:: PIL.Image.Image.point diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 2a6b4646b..96ce96d55 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -915,7 +915,7 @@ class Image: self.load() - has_transparency = self.info.get("transparency") is not None + has_transparency = "transparency" in self.info if not mode and self.mode == "P": # determine default mode if self.palette: @@ -1531,6 +1531,23 @@ class Image: rawmode = mode return list(self.im.getpalette(mode, rawmode)) + def has_transparency_data(self): + """ + 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 == "RGBA") + or "transparency" in self.info + ) + def apply_transparency(self): """ If a P mode image has a "transparency" key in the info dictionary,