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-faceis 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.