SVG 与文本渲染
渲染文本是标签、说明文字和水印构建的常见第一步。libvips 通过 Pango 渲染文本,因此支持标记(<i> 斜体、<span foreground=...> 颜色)、自动换行与对齐。本 Recipe 渲染三种文本样式——基础、自动换行、Pango 标记——分别合成到透明的 640 × 120 RGBA 画布上,并导出为保留 Alpha 的 PNG。
输入是一张尺寸已知、内容为空的透明 SVG 画布;在本 Recipe 中它作为中性基底,不参与合成。
参考输出由 govips v2.19.0 / libvips 8.17.3 实际生成。跨 binding 逐像素对比仍在进行。
基础单行文本
Section titled “基础单行文本”一行 DejaVu Sans 28 文本,渲染为 RGBA 并放在画布左上角。

txt, err := vips.Text(&vips.TextParams{ Text: "VIPS Handbook", Font: "DejaVu Sans 28", DPI: 72, RGBA: true, Wrap: vips.TextWrapWord,})await sharp({ create: { width: 640, height: 120, channels: 4, background: { r: 0, g: 0, b: 0, alpha: 0 } } }) .composite([{ input: { text: { text: 'VIPS Handbook', font: 'DejaVu Sans 28', rgba: true } }, left: 24, top: 24, blend: 'over' }]) .png() .toFile('text-basic.png');canvas = pyvips.Image.black(640, 120, bands=4).cast("uchar").copy(interpretation="srgb")text = pyvips.Image.text("VIPS Handbook", font="DejaVu Sans 28", rgba=True)result = canvas.composite2(text, "over", x=24, y=24)result.write_to_file("text-basic.png")vips black canvas.png 640 120 --bands 4vips copy canvas.png rgba.png --interpretation srgbvips text txt.png "VIPS Handbook" --font 'DejaVu Sans 28' --rgbavips composite2 rgba.png txt.png 'text-basic.png' over --x 24 --y 24自动换行文本
Section titled “自动换行文本”一句较长的句子以 DejaVu Sans 20 在 320 像素宽度内自动换行。透明画布让输出在各 binding 之间保持相同的 640 × 120 尺寸。

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,})await sharp({ create: { width: 640, height: 120, channels: 4, background: { r: 0, g: 0, b: 0, alpha: 0 } } }) .composite([{ input: { text: { text: 'The libvips demand-driven pipeline keeps memory flat while processing large images in production.', font: 'DejaVu Sans 20', width: 320, rgba: true } }, left: 24, top: 24, blend: 'over' }]) .png() .toFile('text-wrapped.png');canvas = pyvips.Image.black(640, 120, bands=4).cast("uchar").copy(interpretation="srgb")text = pyvips.Image.text( "The libvips demand-driven pipeline keeps memory flat while processing large images in production.", font="DejaVu Sans 20", width=320, rgba=True)result = canvas.composite2(text, "over", x=24, y=24)result.write_to_file("text-wrapped.png")vips black canvas.png 640 120 --bands 4vips copy canvas.png rgba.png --interpretation srgbvips text txt.png "The libvips demand-driven pipeline keeps memory flat while processing large images in production." --font 'DejaVu Sans 20' --rgba --width 320vips composite2 rgba.png txt.png 'text-wrapped.png' over --x 24 --y 24Pango 标记
Section titled “Pango 标记”Pango 标记可以在同一个字符串里混合字体粗细、颜色与斜体:粗体紫色的 VIPS 后跟着斜体 Handbook。

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,})await sharp({ create: { width: 640, height: 120, channels: 4, background: { r: 0, g: 0, b: 0, alpha: 0 } } }) .composite([{ input: { text: { text: "<span font_desc='DejaVu Sans' font_size='30000' font_weight='bold' foreground='#5d2f86'>VIPS</span> <i>Handbook</i>", rgba: true } }, left: 24, top: 24, blend: 'over' }]) .png() .toFile('text-pango.png');canvas = pyvips.Image.black(640, 120, bands=4).cast("uchar").copy(interpretation="srgb")text = pyvips.Image.text( "<span font_desc='DejaVu Sans' font_size='30000' font_weight='bold' foreground='#5d2f86'>VIPS</span> <i>Handbook</i>", rgba=True)result = canvas.composite2(text, "over", x=24, y=24)result.write_to_file("text-pango.png")vips black canvas.png 640 120 --bands 4vips copy canvas.png rgba.png --interpretation srgbvips text txt.png "<span font_desc='DejaVu Sans' font_size='30000' font_weight='bold' foreground='#5d2f86'>VIPS</span> <i>Handbook</i>" --rgbavips composite2 rgba.png txt.png 'text-pango.png' over --x 24 --y 24各 binding 如何暴露文本渲染
Section titled “各 binding 如何暴露文本渲染”文本渲染是少数具有可移植核心的“绘图”类操作,但 API 形态各不相同:
- govips 提供手写的
vips.Text(*TextParams)辅助函数,返回独立的*ImageRef。 - sharp 没有独立的文本方法;文本作为叠加层通过
composite([{ input: { text: {...} } }])渲染。 - pyvips 直接暴露
pyvips.Image.text(...)。 - vips CLI 暴露
vips text。
在这里,换行与 Pango 变体有意合成到固定尺寸的透明画布上,使四个 binding 的输出尺寸一致(640 × 120)。如果改为按文本自然尺寸渲染,字形度量取决于系统安装的字体与 DPI,各 binding 的输出可能不同。