Handle Ghostscript rasterization with DPI below 10

Ghostscript may fail when asked to rasterize at very low DPI values
(below 10 on either axis). This adds a workaround that uses a minimum
of 10 DPI for the Ghostscript call, then resizes the output image to
match the dimensions that would have resulted from the original low
DPI request.

Fixes #1612
This commit is contained in:
James R. Barlow
2026-01-31 13:01:04 -08:00
parent 3dd4cde7ce
commit a35fcc9c43
2 changed files with 80 additions and 1 deletions
+24 -1
View File
@@ -127,6 +127,19 @@ def rasterize_pdf(
if not page_dpi:
page_dpi = raster_dpi
# Ghostscript may fail with very low DPI values (below 10). If the requested
# DPI is too low, use a minimum of 10 DPI and resize the output afterward.
MIN_RASTER_DPI = 10
needs_low_dpi_resize = (
raster_dpi.x < MIN_RASTER_DPI or raster_dpi.y < MIN_RASTER_DPI
)
if needs_low_dpi_resize:
effective_dpi = Resolution(
max(raster_dpi.x, MIN_RASTER_DPI), max(raster_dpi.y, MIN_RASTER_DPI)
)
else:
effective_dpi = raster_dpi
args_gs = (
[
GS,
@@ -137,7 +150,7 @@ def rasterize_pdf(
f'-sDEVICE={raster_device}',
f'-dFirstPage={pageno}',
f'-dLastPage={pageno}',
f'-r{raster_dpi.x:f}x{raster_dpi.y:f}',
f'-r{effective_dpi.x:f}x{effective_dpi.y:f}',
]
+ (['-dUseCropBox'] if use_cropbox else [])
+ (['-dFILTERVECTOR'] if filter_vector else [])
@@ -173,6 +186,16 @@ def rasterize_pdf(
try:
with Image.open(output_file) as im:
if needs_low_dpi_resize:
# Resize to the dimensions that would have resulted from the
# original low DPI request
scale_x = raster_dpi.x / effective_dpi.x
scale_y = raster_dpi.y / effective_dpi.y
new_size = (
max(1, int(round(im.width * scale_x))),
max(1, int(round(im.height * scale_y))),
)
im = im.resize(new_size, Image.Resampling.LANCZOS)
if rotation is not None:
log.debug("Rotating output by %i", rotation)
# rotation is a clockwise angle and Image.ROTATE_* is