4

I am trying to convert an image from PNG to EPS using Pillow. The following code gives an error:

from PIL import Image

Image.open("Image1.png").save("Image1.eps", fmt='EPS')

Which reads:

Traceback (most recent call last):
  File "C:/Users/pbreach/Dropbox/Personal/FigureConversion/convert.py", line 15, in <module>
    convert_image(in_name, out_name, fmt='EPS')
  File "C:/Users/pbreach/Dropbox/Personal/FigureConversion/convert.py", line 4, in convert_image
    Image.open(in_name).save(out_name, fmt)
  File "C:\Users\pbreach\Continuum\Anaconda3\lib\site-packages\PIL\Image.py", line 1826, in save
    save_handler(self, fp, filename)
  File "C:\Users\pbreach\Continuum\Anaconda3\lib\site-packages\PIL\EpsImagePlugin.py", line 362, in _save
    raise ValueError("image mode is not supported")
ValueError: image mode is not supported

Is EPS really not supported? In the documentation EPS is second on the list of fully supported formats. Is there anything that I need to do if this is not the case?

Weirdly enough, if I do Image.open("Image1.png").save("Image1.jpg", fmt='EPS') it works but saves to JPG.

pbreach
  • 16,049
  • 27
  • 82
  • 120

2 Answers2

3

Pillow supports EPS, but cannot write it with alpha channel (RGBA, LA) https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html?highlight=eps#eps:

Pillow identifies EPS files containing image data, and can read files that contain embedded raster images (ImageData descriptors). If Ghostscript is available, other EPS files can be read as well. The EPS driver can also write EPS images. The EPS driver can read EPS images in L, LAB, RGB and CMYK mode, but Ghostscript may convert the images to RGB mode rather than leaving them in the original color space. The EPS driver can write images in L, RGB and CMYK modes.

Helped for me to convert the image to RGB mode before saving

from PIL import Image

fig = Image.open("Image1.png")

if fig.mode in ('RGBA', 'LA'):
    # https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html?highlight=eps#eps
    print('Current figure mode "{}" cannot be directly saved to .eps and should be converted (e.g. to "RGB")'.format(fig.mode))
    fig = fig.convert('RGB')

out_fig = "Image1.eps"
fig.save(out_fig)
fig.close()

But sometimes I had problems: got black background in .eps instead of transparent .png. For me helped remove_transparency() function from https://stackoverflow.com/a/35859141/7444782 to substitute the transparent background to a specified color (white by default)

from PIL import Image

def remove_transparency(im, bg_color=(255, 255, 255)):
    """
    Taken from https://stackoverflow.com/a/35859141/7444782
    """
    # Only process if image has transparency (http://stackoverflow.com/a/1963146)
    if im.mode in ('RGBA', 'LA') or (im.mode == 'P' and 'transparency' in im.info):

        # Need to convert to RGBA if LA format due to a bug in PIL (http://stackoverflow.com/a/1963146)
        alpha = im.convert('RGBA').split()[-1]

        # Create a new background image of our matt color.
        # Must be RGBA because paste requires both images have the same format
        # (http://stackoverflow.com/a/8720632  and  http://stackoverflow.com/a/9459208)
        bg = Image.new("RGBA", im.size, bg_color + (255,))
        bg.paste(im, mask=alpha)
        return bg
    else:
        return im

fig = Image.open("Image1.png")

if fig.mode in ('RGBA', 'LA'):
    # https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html?highlight=eps#eps
    print('Current figure mode "{}" cannot be directly saved to .eps and should be converted (e.g. to "RGB")'.format(fig.mode))
    fig = remove_transparency(fig)
    fig = fig.convert('RGB')

out_fig = "Image1.eps"
fig.save(out_fig)
fig.close()
and1er
  • 749
  • 8
  • 18
0

It might be that you have a png with an alpha channel. EPS in PIL does not support transparency in raster images.

So if you remove the alpha channel by im[:,:,0:2] it might just work like a charm. It will be more than one line, however.

Anderas
  • 630
  • 9
  • 20