diff --git a/Tests/images/reqd_showpage_transparency.png b/Tests/images/reqd_showpage_transparency.png new file mode 100644 index 000000000..3ce159d0f Binary files /dev/null and b/Tests/images/reqd_showpage_transparency.png differ diff --git a/Tests/test_file_eps.py b/Tests/test_file_eps.py index 1994a124c..4c0b96f73 100644 --- a/Tests/test_file_eps.py +++ b/Tests/test_file_eps.py @@ -96,6 +96,17 @@ def test_showpage(): assert_image_similar(plot_image, target, 6) +@pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available") +def test_transparency(): + with Image.open("Tests/images/reqd_showpage.eps") as plot_image: + plot_image.load(transparency=True) + assert plot_image.mode == "RGBA" + + with Image.open("Tests/images/reqd_showpage_transparency.png") as target: + # fonts could be slightly different + assert_image_similar(plot_image, target, 6) + + @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available") def test_file_object(tmp_path): # issue 479 diff --git a/docs/handbook/image-file-formats.rst b/docs/handbook/image-file-formats.rst index 5d4e83494..06d262d43 100644 --- a/docs/handbook/image-file-formats.rst +++ b/docs/handbook/image-file-formats.rst @@ -66,7 +66,7 @@ than leaving them in the original color space. The EPS driver can write images in ``L``, ``RGB`` and ``CMYK`` modes. If Ghostscript is available, you can call the :py:meth:`~PIL.Image.Image.load` -method with the following parameter to affect how Ghostscript renders the EPS +method with the following parameters to affect how Ghostscript renders the EPS **scale** Affects the scale of the resultant rasterized image. If the EPS suggests @@ -79,6 +79,11 @@ method with the following parameter to affect how Ghostscript renders the EPS im.load(scale=2) im.size #(200,200) +**transparency** + If true, generates an RGBA image with a transparent background, instead of + the default behaviour of an RGB image with a white background. + + GIF ^^^ diff --git a/docs/releasenotes/8.4.0.rst b/docs/releasenotes/8.4.0.rst index 7043e44ec..e23a1eefe 100644 --- a/docs/releasenotes/8.4.0.rst +++ b/docs/releasenotes/8.4.0.rst @@ -19,6 +19,18 @@ the default required length, also removing the need for the size parameter. API Additions ============= +Added "transparency" argument for loading EPS images +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This new argument switches the Ghostscript device from "ppmraw" to "pngalpha", +generating an RGBA image with a transparent background instead of an RGB image with a +white background. + +.. code-block:: python + + with Image.open("sample.eps") as im: + im.load(transparency=True) + Added WalImageFile class ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/PIL/EpsImagePlugin.py b/src/PIL/EpsImagePlugin.py index 3b7eacbfc..5d9920280 100644 --- a/src/PIL/EpsImagePlugin.py +++ b/src/PIL/EpsImagePlugin.py @@ -61,7 +61,7 @@ def has_ghostscript(): return False -def Ghostscript(tile, size, fp, scale=1): +def Ghostscript(tile, size, fp, scale=1, transparency=False): """Render an image using Ghostscript""" # Unpack decoder tile @@ -108,6 +108,8 @@ def Ghostscript(tile, size, fp, scale=1): lengthfile -= len(s) f.write(s) + device = "pngalpha" if transparency else "ppmraw" + # Build Ghostscript command command = [ "gs", @@ -117,7 +119,7 @@ def Ghostscript(tile, size, fp, scale=1): "-dBATCH", # exit after processing "-dNOPAUSE", # don't pause between pages "-dSAFER", # safe mode - "-sDEVICE=ppmraw", # ppm driver + f"-sDEVICE={device}", f"-sOutputFile={outfile}", # output file # adjust for image origin "-c", @@ -325,11 +327,11 @@ class EpsImageFile(ImageFile.ImageFile): return (length, offset) - def load(self, scale=1): + def load(self, scale=1, transparency=False): # Load EPS via Ghostscript if not self.tile: return - self.im = Ghostscript(self.tile, self.size, self.fp, scale) + self.im = Ghostscript(self.tile, self.size, self.fp, scale, transparency) self.mode = self.im.mode self._size = self.im.size self.tile = []