Blurry logo or QR code in your PDF? Use SVG or higher-resolution images

Measured: images print at their own pixels, canvases at 96 ppi, and SVG as sharp vectors with selectable text.

Updated · 4 min read

A logo that looks crisp on screen can look soft in the PDF, especially when someone zooms in or prints it. The cause is almost always resolution. We drew the same small graphic four ways and zoomed in on the PDF.

Four zoomed-in samples of the text Q3 £48,210 and a curved line. Inline SVG is perfectly sharp. Canvas at 1x is pixelated. Canvas at 3x is sharp. A PNG at its display size is pixelated.
The same 180×90 graphic, zoomed in on the PDF. Only SVG and the 3× canvas stay sharp.

What we measured

Drawn asIn the PDF
Inline SVGVector shapes and real text: sharp at any zoom, text selectable
PNG, 180×90 pixels, shown at 180×90Image at 96 ppi
PNG or JPEG, 540×270, shown at 180×90Image at 288 ppi, original file kept (a JPEG stays a JPEG)
Canvas, 180×90Image at 96 ppi
Canvas, 540×270 shown at 180×90Image at 288 ppi

One CSS pixel is 1/96 of an inch, so an image with one pixel per CSS pixel prints at 96 pixels per inch (ppi). Print usually wants around 300 ppi.

Fixes

  • Use SVG for logos, icons, signatures and QR codes. Inline <svg> stays a vector. Most QR and barcode libraries can output SVG instead of canvas.
  • For photos and other bitmaps, supply about 3× the pixels and set the display size in HTML: a 600×300 image shown at width="200" height="100" prints at 288 ppi.
  • For canvases, scale the backing store. The converter reports devicePixelRatio as 1, so code that scales by it draws at 96 ppi. Set a larger canvas and scale the drawing context yourself:
const scale = 3;
canvas.width = 180 * scale;  canvas.height = 90 * scale;
canvas.style.width = "180px"; canvas.style.height = "90px";
const ctx = canvas.getContext("2d");
ctx.scale(scale, scale);   // then draw using 180×90 coordinates

For Chart.js, the devicePixelRatio: 3 option does the same; see charts in HTML to PDF.

Mind the file size

Higher resolution means bigger files. A few logos at 3× cost very little, but dozens of large photos can push a PDF past the 20 MiB limit. Our photo case study has the numbers. Use JPEG for photos and SVG or PNG for flat graphics.

QR codes

Scanners need clean edges between modules. An SVG QR code with shape-rendering="crispEdges" printed perfectly sharp in our test, and keep a white margin of at least four modules around it.