Pixelated images in SVG
- Last updated
SVG, as its name suggests, is designed for scalable vector graphics.
However, the format also supports raster graphics with
By default, the raster images are usually upscaled smoothly which is unsuitable for pixel art and close-ups of image data.
In this article we're checking out how this behavior can be changed in different SVG renderers.
There's a promising attribute called
image-rendering which hints whether the rendered should optimize for rendering speed or quality.
Below you can see how different values of this attribute work in your browser on a simple 2 × 2 image:
Based on my tests only Firefox and Inkscape give out the desired output with
So we cannot rely on the
image-rendering attribute which is, after all, only a hint.
SVG also supports CSS which has a similarly named
pixelated looks exactly like what we need as it should preserve the pixelated look.
crisp-edges which could, at least in theory, use a pixel-art scaling algorithm.
Test your browser below:
It seems that Chrome supports
pixelated but Firefox doesn't.
To support both these browsers, we can use both the
image-rendering attribute and property:
<image image-rendering="optimizeSpeed" style="image-rendering:pixelated" />
Unfortunately, controlling image rendering doesn't seem to possible at all in Safari and SVG renderers like librsvg.
There are two workarounds: upscaling the image in advance and recreating the image with vector shapes.
image-rendering option against the workarounds on an image at 4x scaling:
The above file sizes are calculated after optimizing the embedded images with oxipng, running svgcleaner and gzipping everything. As we can see, file sizes of the workarounds are a bit larger than the original. To keep the upscaled image sharp on all displays, 16x scaling is used instead of 4x scaling, because the display may have a pixel ratio up to 4 and 4 × 4 = 16. Additionally, gaps between pixels can be visible in the vectorized image especially when displayed at different zoom levels.
Overall upscaling seems to be the better workaround in terms of file size and clean rendering. However, you might be able to handcraft a much smaller SVG depending on the style and complexity of your image.