node.js 文字转图片

之前在 cnodejs.org 回复过一个答案。最近 cnodejs.org 无法访问,只能找快照把代码拷贝出来。果然还是自己的服务器靠谱一点。

简介

在日常开发中,我们经常需要将文字转换为图片,比如生成海报、邀请函、证书等。本文将介绍如何使用 Node.js 结合 TextToSVGSharp 库来实现高质量的文字转图片功能。

实现原理

整个过程分为以下几个步骤:

  1. 使用 TextToSVG 将文字转换为 SVG 格式
  2. 使用 Sharp 库加载背景图片和 SVG 文字
  3. 计算文字在背景图上的位置并合成
  4. 输出最终的 PNG 图片

完整代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
const TextToSVG = require('text-to-svg');
const sharp = require('sharp');

// 计时开始
console.time("png");

// 加载字体文件
const textToSVG = TextToSVG.loadSync('./DENG.TTF');

// 创建三段不同样式的文字 SVG
const svg1 = textToSVG.getSVG('魏长青-人人讲 App', {
x: 0,
y: 0,
fontSize: 24,
anchor: 'top',
});

const svg2 = textToSVG.getSVG('邀请您参加', {
x: 0,
y: 0,
fontSize: 16,
anchor: 'top',
});

const svg3 = textToSVG.getSVG('人人讲课程', {
x: 0,
y: 0,
fontSize: 32,
anchor: 'top',
});

// 异步处理图片合成
(async () => {
// 加载背景图和文字 SVG
const sourceImg = sharp('./bg.png');
const target1Img = sharp(Buffer.from(svg1));
const target2Img = sharp(Buffer.from(svg2));
const target3Img = sharp(Buffer.from(svg3));

// 并行获取所有图片的元数据
const [
{width:sWidth , height:sHeight },
{width:t1Width , height:t1Height },
{width:t2Width , height:t2Height },
{width:t3Width , height:t3Height }
] = await Promise.all([
sourceImg.metadata(),
target1Img.metadata(),
target2Img.metadata(),
target3Img.metadata()
]);

// 计算每段文字的位置(居中对齐)
const offsetX1 = parseInt((sWidth - t1Width) / 2);
const offsetY1 = 200;

const offsetX2 = parseInt((sWidth - t2Width) / 2);
const offsetY2 = 240;

const offsetX3 = parseInt((sWidth - t3Width) / 2);
const offsetY3 = 270;

// 并行转换 SVG 为图片缓冲区
const [target1Buffer, target2Buffer, target3Buffer] = await Promise.all([
target1Img.toBuffer(),
target2Img.toBuffer(),
target3Img.toBuffer()
]);

// 合成图片并输出
await sourceImg
.composite([
{input: target1Buffer, left: offsetX1, top: offsetY1},
{input: target2Buffer, left: offsetX2, top: offsetY2},
{input: target3Buffer, left: offsetX3, top: offsetY3}
])
.sharpen()
.withMetadata()
.png()
.toFile('./card.png');

console.log('图片生成成功:./card.png');
})()

// 输出执行时间
console.timeEnd("png");

代码解析

1. 依赖库介绍

  • TextToSVG:将文字转换为 SVG 路径的库,支持自定义字体
  • Sharp:高性能的 Node.js 图像处理库,支持多种图像格式

2. 关键步骤说明

  1. 字体加载TextToSVG.loadSync('./DENG.TTF') 加载本地中文字体文件
  2. SVG 生成:通过 getSVG() 方法将文字转换为 SVG 格式
  3. 并行处理:使用 Promise.all() 并行获取图片元数据,提升性能
  4. 位置计算:通过 (背景图宽度 - 文字宽度) / 2 实现水平居中
  5. 图片合成:使用 Sharp 的 composite() 方法将文字叠加到背景图上

优化建议

  1. 错误处理:添加适当的错误处理机制
  2. 参数配置:将文字内容、字体大小等提取为配置参数
  3. 字体管理:建立字体管理系统,支持多种字体切换
  4. 内存优化:对于大量图片处理,注意内存管理和释放

使用方法

  1. 安装依赖:

    1
    npm install text-to-svg sharp
  2. 准备字体文件和背景图(DENG.TTF 和 bg.png)

  3. 运行脚本:

    1
    node text-to-image.js

总结

通过 TextToSVG 和 Sharp 的组合,我们可以轻松实现高质量的文字转图片功能。这种方法具有以下优势:

  • 支持自定义字体,解决中文显示问题
  • 利用 Sharp 的高性能图像处理能力
  • 通过并行处理提升执行效率
  • 灵活的位置控制和样式设置

这种方法适用于生成各种类型的图片,如海报、证书、邀请函等场景。


node.js 文字转图片
https://bubao.github.io/posts/576aa3eb.html
作者
一念
发布于
2020年10月18日
许可协议