The decision

Carried as-is GIF, JPEG, PNG
Converted to PNG anything GD can decode — WebP, BMP
Rasterised SVG, when ext-imagick can draw it
Refused anything else, anything unreadable, anything too large

A format nothing here can decode is refused by name, with a message naming the format. It is never drawn as a placeholder, because a deck with a picture missing is the one outcome this suite refuses to produce anywhere.

Alpha survives a conversion: the alpha channel is kept and the result is written as PNG.

The ceiling

16,777,216 pixels — 4096 by 4096 — on both halves, enforced on the header.

This is worth a moment, because the obvious implementation of it is wrong. Measuring a raster means decoding it, and decoding a picture is what allocates the memory you were trying to bound. For a vector it is worse: a file of 152 bytes declaring a 16000-square drawing is a file that wants a 1.9 GB canvas before anything has decided whether it may have one.

So both halves read the size without drawing:

152-byte SVG  ->  refused in 0.05s, 4 MB peak

which is what pingImage() is for. It reads the header and stops, and the header is worth trusting because the delegate sizes the canvas from the same header: a file declaring width="10" beside a viewBox of 9000 is drawn at 10, not at 9000.

There is no second line of defence, and it is worth saying why rather than shipping one. ImageMagick's own resource limits do not bound an SVG render: measured against a 4000-square file, -limit area 1000 -limit memory 4MiB -limit map 4MiB on the command line produced the picture anyway. An area limit would have read as protection and been nothing.

SVG

Word and PowerPoint both hold a vector only beside a raster of it, so something has to draw the raster. GD has no entry point for a vector in any PHP version, so ext-imagick is the only rasteriser here — and it is in suggest, not require.

"ext-imagick": "Embeds SVG. PowerPoint holds a vector only beside a raster of it, so
something has to draw the raster; without this an SVG raises rather than going in as a picture
no reader can show."

Without it, an SVG is refused by name rather than rasterised badly.

A build is not just "is the extension loaded". SvgRasteriser::available() renders a probe and checks for ink. A build of ImageMagick with no fonts configured answers --version perfectly and draws every <text> as nothing; that is a real configuration found on a real machine, and the probe is what catches it.

What SVG costs you

The part in the package is a PNG, not the vector. What appears in the deck is what this rasteriser drew, not what the file described — and:

  • A <text> is in the picture only as far as the delegate draws a letter.
  • An SVG carrying its own font as a data-URI @font-face is silently substituted. The render comes out identical to the "that family does not exist" fallback. Nothing detects this; it is documented here because it costs an afternoon otherwise.

Every example on this page was built by the library it documents while this page was built. This page as Markdown.