Node.js终极文本转图指南
引言
简要介绍文字转图片的应用场景(如社交媒体分享、水印生成、动态海报等),以及Node.js在图像处理中的优势。提及ultimate-text-to-image库的核心功能和特点。
环境准备
所需工具和库的版本要求:
- Node.js
- npm或yarn包管理器
- ultimate-text-to-image库的安装命令:
npm install ultimate-text-to-image
UltimateTextToImage 基本用法
UltimateTextToImage
是一个用于将文本转换为图像的 Node.js 库,支持多种自定义选项如字体、颜色、对齐方式等。通过简单的配置,可以生成不同风格的文本图像。
将文本`abc xyz 0123456789 零一二三四五六七八九`转化为图片,图片宽度为200像素,字体为‘Sans,Arial’,首选‘Sans’,次选‘Arial’。将图片保存到项目的根目录下,图片名称为‘image1.png’
const { UltimateTextToImage } = require("ultimate-text-to-image");
const path = require("path");new UltimateTextToImage(`abc xyz 0123456789 零一二三四五六七八九`, {width: 200,fontFamily: "Sans,Arial", //有些字体可能不支持中文
}).render().toFile(path.join(__dirname, "image1.png"));
执行后的效果图:
高级配置选项
该库提供了丰富的配置参数,允许用户精细控制文本的显示效果。包括字体大小、颜色、背景、边框等属性,满足不同场景需求。
let textToImage = new UltimateTextToImage("abc xyz 0123456789 零一二三四五六七八九",{width: 400, // 初始画布宽度(px),若文本超出会自动调整maxWidth: 1000, // 画布最大宽度(px),防止无限扩展maxHeight: 1000, // 画布最大高度(px),超出可能截断fontFamily: "Sans", // 字体(系统支持的字体,如 "Arial"、"SimSun")fontColor: "#00FF00", // 文字颜色(十六进制或RGB,支持透明度如 `#00FF0080`)fontSize: 72, // 初始字体大小(px)minFontSize: 10, // 最小字体大小lineHeight: 50, // 基础行高(px)autoWrapLineHeightMultiplier: 1.2, //换行时的行高倍数margin: 20, // 四周边距(px),会被 `marginBottom` 覆盖marginBottom: 40, // 底部边距(优先级高于 `margin`)align: "center", // 水平对齐:"left" | "center" | "right"valign: "middle", // 垂直对齐:"top" | "middle" | "bottom"borderColor: 0xff000099, // 边框颜色(十六进制或十进制,支持透明度)borderSize: 2, // 边框宽度(px)backgroundColor: "0080FF33", // 背景色(支持透明度,如 `"rgba(0,128,255,0.2)"`)underlineColor: "#00FFFF33", // 下划线颜色(支持透明度)underlineSize: 2, // 下划线粗细(px)}
);textToImage.render().toFile(path.join(__dirname, "image2.png"));
运行后的效果图:
图像属性获取
生成图像后,可以获取各种属性信息,如画布尺寸、渲染时间等。这些属性对于调试和优化图像生成过程非常有用。
let textToImage = new UltimateTextToImage("文本内容",{width: 400,}
);//等待渲染
await textToImage.render();// 画布的最终宽度
const width = textToImage.width; // 画布的最终高度
const height = textToImage.height;// 画布的渲染时间
const renderedTime = textToImage.renderedTime;//包含文本在渲染前的详细测量信息,例如每行文本的尺寸、位置等
const measuredParagraph = textToImage.measuredParagraph; 获取画布对象
const canvas = textToImage.canvas; //是否已执行过渲染操作(render() 方法是否被调用过)。
const hasRendered = textToImage.hasRendered;
运行后的结果:
画布宽度: 929
画布高度: 210
画布渲染时间(ms): 673.5504
文字信息: {text: 'abc xyz 0123456789 零一二三四五六七八九',width: 890.859375,height: 158,fontSize: 72,fontFamily: 'Sans',fontStyle: false,fontWeight: false,spaceWidth: 22.5,boundingHeight: 150,boundingWidth: 889.859375,paddingTop: -15,paddingBottom: 7,paddingLeft: 3,paddingRight: -1,measuredLines: [{text: 'abc xyz 0123456789 零一二',width: 890.859375,paddingTop: -15,paddingBottom: 14,paddingLeft: 1,paddingRight: -2,nextLineHeight: 86,measuredWords: [Array]},{text: '三四五六七八九',width: 504,paddingTop: -13,paddingBottom: 7,paddingLeft: 3,paddingRight: -1,nextLineHeight: 0,measuredWords: [Array]}]
}
画布对象: [Canvas 929x210]
画布是否渲染 true
动态修改与重新渲染
支持动态修改配置选项并重新渲染图像。这种灵活性使得可以在不创建新实例的情况下调整图像样式。
let textToImage = new UltimateTextToImage(`abc xyz 0123456789 零一二三四五六七八九`, {width: 200,fontFamily: "Sans",
}).render().toFile(path.join(__dirname, "image1.png"));textToImage.options.fontFamily = "Comic Sans MS";
textToImage.render().toFile("updated.png");
运行后的结果(Comic Sans MS字体不支持中文):
数据URL输出
除了保存为文件,还可以将图像转换为数据URL格式,便于网页直接使用或嵌入其他应用。
//默认png
let textToImage = new UltimateTextToImage("Hello World").render();
const dataUrlPng = textToImage.toDataUrl(); // image/png by default
console.log(dataUrlPng);// 0 到 100,其中 100 表示最高质量(无损但文件最大),
//80 表示一个较高的质量但文件大小相对较小。
const dataUrlJpeg = textToImage.toDataUrl("image/jpeg", { quality: 80 });
console.log(dataUrlJpeg);
运行后的效果:
data:image/png;base64,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
缓冲流输出
支持将图像转换为缓冲流,便于进一步处理或传输。提供多种格式选项和压缩参数,平衡质量与大小。
// 图片转buffer
const buffer = textToImage.toBuffer(); // 默认png
//0 表示无压缩(文件最大但最快),9 表示最大压缩
const bufferPng = textToImage.toBuffer("image/png", { compressionLevel: 6 });
// progressive设置渐进式 JPEG 图像,在加载时会逐渐从低分辨率到高分辨率显示
const bufferJpeg = textToImage.toBuffer("image/jpeg", {//100:最高质量(几乎无损,文件最大)。0:最低质量(严重失真,文件最小)。quality: 80, progressive: true,});
画布转换为流并保存为图片
将文本生成的图片转换为可读流,然后通过管道传输到可写流中完成文件保存。
let textToImage = new UltimateTextToImage("Hello World").render();// 图片转stream
const streamPng = textToImage.toStream(); // 默认生成png格式
const streamJpeg = textToImage.toStream("image/jpeg"); // 指定生成jpeg格式
const out = fs.createWriteStream(path.join(__dirname, "imageE4.png"));
streamPng.pipe(out);
运行后的效果:
多种格式的图像拼接
以下代码展示了如何使用 UltimateTextToImage
库加载多种格式的图像数据(URL、Base64、Buffer、ArrayBuffer),并通过不同方式将这些图像绘制到画布上:
const {UltimateTextToImage,getCanvasImage
} = require("ultimate-text-to-image");(async () => {const url ="https://www.npmjs.com/npm-avatar/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdmF0YXJVUkwiOiJodHRwczovL3MuZ3JhdmF0YXIuY29tL2F2YXRhci8yNjljMGE1MzNiNTQ1MDNkMDg2Y2EwYWJlMzBkODkwNT9zaXplPTEwMCZkZWZhdWx0PXJldHJvIn0.W4Iy2ZRyJ3XX_ju-P_zdYhVlRrONO0ZYJn4iRQw5eFM";const buffer = new UltimateTextToImage("repeatX").render().toBuffer();const base64 = new UltimateTextToImage("fitY").render().toBuffer().toString("base64");const arrayBuffer = new Uint8Array(new UltimateTextToImage("repeat").render().toBuffer());const canvasImage1 = await getCanvasImage({ url });const canvasImage2 = await getCanvasImage({ base64 });const canvasImage3 = await getCanvasImage({ buffer });const canvasImage4 = await getCanvasImage({ arrayBuffer });const textToImage = new UltimateTextToImage("Image Example", {width: 600,height: 600,alignToCenterIfLinesLE: 1,fontSize: 72,backgroundColor: "#FFFFFF99",images: [{ canvasImage: canvasImage1, layer: -1, repeat: "fit" },{canvasImage: canvasImage2,layer: 0,repeat: "fitY",x: 10,y: 10,width: 100,height: 100,},{canvasImage: canvasImage3,layer: 1,repeat: "repeatX",sx: -400,sy: 100,width: 300,height: 300,},{canvasImage: canvasImage4,layer: 1,repeat: "repeat",sx: -200,sy: -300,tx: -50,ty: -50,},],}).render().toFile(path.join(__dirname, "image4.png"));
})();
核心功能说明
图像加载
代码中使用四种不同来源加载图像:URL、Base64字符串、Buffer对象和ArrayBuffer对象。getCanvasImage
函数处理这些不同格式的输入并返回可绘制的图像对象。图像绘制参数
layer
: 控制图像的绘制层级,数值越小越先绘制repeat
: 指定图像的重复模式(fit/fitY/repeatX/repeat)x/y
: 图像绘制的位置坐标width/height
: 控制绘制尺寸sx/sy
: 源图像裁剪起始点tx/ty
: 目标画布绘制起始点
输出处理
最终通过toFile()
方法将合成结果保存为PNG文件,也可以使用toBuffer()
获取二进制数据用于进一步处理。
运行后的效果图:
文本到图像的渲染控制
动态生成图像时,同时利用 preRender
和 posRender
回调函数在渲染前后执行自定义逻辑。例如:
let textToImage = new UltimateTextToImage("Rendering",{},{preRender: (canvas) => {// 在绘制任何内容前触发(调用 render() 时)console.log("before");console.log(canvas);},posRender: (canvas) => {// 在绘制完所有文本和图像后触发console.log("after");console.log(canvas);},}
).render();
关键点说明
preRender
:在渲染开始前调用,可用于初始化画布状态或记录调试信息。posRender
:在渲染完成后调用,适合对生成的图像进行后处理或保存操作。
混合布局图像
const {UltimateTextToImage,HorizontalImage,VerticalImage,
} = require("ultimate-text-to-image");
const path = require("path");const textToImage1 = new UltimateTextToImage("Image1", {backgroundColor: "#0080FF33",fontSize: 60,
});
const textToImage2 = new UltimateTextToImage("Image2 ".repeat(10).trim(), {maxWidth: 200,backgroundColor: "#00FF0033",fontSize: 40,
});const horizontalImage = new HorizontalImage([textToImage1,textToImage2,new HorizontalImage([new UltimateTextToImage("Horizontal 1"),new UltimateTextToImage("Horizontal 2", { fontSize: 50 }),]),new VerticalImage([new UltimateTextToImage("Vertical 1"),new UltimateTextToImage("Vertical 2", { fontColor: "#FF0000" }),]),],{ valign: "bottom", backgroundColor: "#AAAAAA", margin: 100 }
);horizontalImage.render().toFile(path.join(__dirname, "imageMixed1.jpg"));
功能说明
- 基础文本图像:
textToImage1
和textToImage2
分别生成带有不同背景色和字体大小的文本图像。 - 嵌套布局:
HorizontalImage
和VerticalImage
实现水平和垂直方向的混合布局。 - 样式配置:通过
valign
、backgroundColor
和margin
参数控制整体对齐、背景色和边距。 - 输出文件:最终图像通过
render().toFile()
保存为本地文件。
运行后的效果图: