Pillow
| Language | Python |
|---|---|
| License | MIT-CMU (HPND) |
| Repository | github.com/python-pillow/Pillow |
| Documentation | EPS/PS format notes, PSDraw |
| Depends on | the Ghostscript executable (gs, or gswin64c on Windows) for reading |
| Read / write | yes (first page, rasterized by Ghostscript) / yes (raster EPS; PSDraw writes PostScript pages) |
Pillow’s EpsImagePlugin handles both .eps and .ps (any file starting with %!PS). When you load the pixels, Pillow runs the Ghostscript executable on the file and reads back the bitmap. The image size comes from the %%BoundingBox comment, so a file without one fails to open (“cannot determine EPS bounding box”).
Pillow reads only the first page and is meant for thumbnails and simple conversions. For multi-page PostScript, PDF conversion or text, use python-ghostscript. For writing, PSDraw produces simple PostScript pages with text, lines, rectangles and images.
Installation#
pip install pillow
# Ghostscript for reading
sudo apt install ghostscript # Debian / Ubuntu
brew install ghostscript # macOS
On Windows install Ghostscript from ghostscript.com; Pillow looks for gswin64c and gswin32c on PATH.
Basic usage: render a PostScript file to PNG#
from PIL import Image
with Image.open("in.ps") as im:
print(im.format, im.size) # size in points from %%BoundingBox
im.load(scale=4) # 4x: 288 dpi instead of 72 dpi
im.save("out.png")
How to get a transparent background#
from PIL import Image
with Image.open("in.ps") as im:
im.load(scale=2, transparency=True) # RGBA instead of RGB on white
im.save("out.png")
How to make a thumbnail of a PostScript file#
from PIL import Image
with Image.open("in.ps") as im:
im.load(scale=2)
im.thumbnail((300, 300))
im.convert("RGB").save("thumb.jpg", quality=85)
How to draw a PostScript page with PSDraw#
Coordinates are in points with the origin at the bottom-left of the page:
from PIL import Image, PSDraw
with open("out.ps", "wb") as fp:
ps = PSDraw.PSDraw(fp)
ps.begin_document()
ps.setfont("Helvetica-Narrow-Bold", 24)
ps.text((72, 720), "Hello, PostScript")
ps.line((72, 700), (540, 700))
ps.rectangle((72, 500, 200, 150)) # x, y, width, height
with Image.open("photo.jpg") as im:
ps.image((72, 100, 540, 450), im, 150) # fit into the box at 150 dpi
ps.end_document()
How to use a specific Ghostscript executable#
from PIL import EpsImagePlugin
EpsImagePlugin.gs_binary = r"C:\Program Files\gs\gs10.05.1\bin\gswin64c.exe"
Set it to False to stop Pillow from calling Ghostscript (opening then fails for files without an embedded preview).
Tips#
- Pillow passes
-dSAFERto Ghostscript, but the file still runs as a program: limit the size and time for files from users. - Only the first page is read. To split a multi-page file, render with Ghostscript (
-sDEVICE=png16m -sOutputFile=page-%03d.png) and open the PNG files.