Skip to content

SVG and text rendering

Copy page

Rendering text is a common first step for labels, captions, and watermark building. libvips renders text through Pango, so you get markup (<i> italic, <span foreground=...> colour), word wrapping, and alignment. This recipe renders three text styles — basic, wrapped, and Pango markup — each composited onto a transparent 640 × 120 RGBA canvas and exported as PNG with alpha preserved.

The input is an empty transparent SVG canvas of known dimensions; it acts as a neutral base and is not composited in this recipe.

Empty transparent SVG canvas used as the text-rendering base
Input: SVG800 × 200, transparent

The reference output was generated with govips v2.19.0 / libvips 8.17.3. Cross-binding pixel comparison is still pending.

One line of text at DejaVu Sans 28, rendered to RGBA and placed at the top-left of the canvas.

Single-line VIPS Handbook text on a transparent canvas
text-basic: PNGDejaVu Sans 28, RGBA
txt, err := vips.Text(&vips.TextParams{
Text: "VIPS Handbook",
Font: "DejaVu Sans 28",
DPI: 72,
RGBA: true,
Wrap: vips.TextWrapWord,
})

A longer sentence wrapped to a 320 pixel width at DejaVu Sans 20. The transparent canvas keeps the output the same 640 × 120 size across bindings.

A long sentence wrapped to a 320-pixel width inside the transparent canvas
text-wrapped: PNGDejaVu Sans 20, width 320, word wrap
txt, err := vips.Text(&vips.TextParams{
Text: "The libvips demand-driven pipeline keeps memory flat while processing large images in production.",
Font: "DejaVu Sans 20",
DPI: 72,
Width: 320,
RGBA: true,
Wrap: vips.TextWrapWord,
})

Pango markup mixes font weight, colour, and italic in a single string: bold violet VIPS followed by an italic Handbook.

Pango-markup text mixing bold violet and italic on a transparent canvas
text-pango: PNGPango markup, RGBA
txt, err := vips.Text(&vips.TextParams{
Text: "<span font_desc='DejaVu Sans' font_size='30000' font_weight='bold' foreground='#5d2f86'>VIPS</span> <i>Handbook</i>",
Font: "DejaVu Sans",
DPI: 72,
RGBA: true,
Wrap: vips.TextWrapWord,
})

Text rendering is the one “drawing”-like operation with a shared portable core, but the API shape differs:

  • govips has a hand-written vips.Text(*TextParams) helper that returns a standalone *ImageRef.
  • sharp has no standalone text method; text is rendered as an overlay via composite([{ input: { text: {...} } }]).
  • pyvips exposes pyvips.Image.text(...) directly.
  • vips CLI exposes vips text.

The wrapped and Pango variants here were intentionally composited onto a fixed-size transparent canvas so the output dimensions are identical across all four bindings (640 × 120). If you render text at its natural size instead, the glyph metrics depend on the installed font set and DPI, and the output can differ between bindings.