libvips / pyvips

python binding for libvips using cffi
MIT License
649 stars 50 forks source link

SVG rendering failed #439

Open reyvateil opened 11 months ago

reyvateil commented 11 months ago

Hi, I am attempting to draw polygons onto an Image using svgload_buffer. The Image size is roughly 100k×200k. The problem arises when I try to read data from the created mask. Cropping, fetching or converting to numpy results in the following error:

# Create polygon image, scale it, drop alpha channel
im = pyvips.Image.svgload_buffer(
    svg_xml.encode(),
    scale=1/2,
    unlimited=True
)[:3]
_ = im.numpy()

(process:2080544): librsvg-WARNING **: 15:27:48.699: cannot render on a cairo_t with a failure status (status=InvalidSize)
Error: unable to write to memory
  svgload_buffer: SVG rendering failed
glib: rendering error: InvalidSize

Funnily enough, using scale 1/4 and smaller does not result in the error. Similarly, scaling the image down, then back up, and then reading from it also does not result in the error:

# This works fine
im = pyvips.Image.svgload_buffer(
    svg_xml.encode(),
    scale=1/32,
    unlimited=True
)[:3]
_ = im.numpy()

# This also works fine, despite having the same dimensions
# as the errorneous example above
im = pyvips.Image.svgload_buffer(
    svg_xml.encode(),
    scale=1/32,
    unlimited=True
)[:3]
im = im.resize(16)
_ = im.numpy()

Thanks in advance.

jcupitt commented 11 months ago

Hello @reyvateil,

Unfortunately, Cairo has a hard limit of 32k pixels in any axis, so your image is just too big :( libvips used to have a workaround (it rendered SVGs in sections), but sadly that is no longer supported by librsvg.

We've been talking about switching to another SVG load library that doesn't have this limitation, but no one's done the work yet.

https://github.com/libvips/libvips/discussions/2048