闲谈
还在为写文章时找不到标题图片而困扰吗?举个例子,CSDN
的博客文章如果你不给他图片的话,那么它会按照一些默认的标签图片作为你的文章封面,例如下面这样。
但这样有一个问题,如果你写了很多篇的前端文章,那么这些图片都是#前端
,就不好通过这些封面图片分辨不同的文章了,为了解决这个问题,本篇文章于是就应运而生啦。
正文
需求和环境搭建
我的需求
:我打算通过一个带标题的请求生成对应的一张标题图片。
所以我需要使用一个后端框架作为服务层,这里我采用的是Node
的Express
框架。
由于我要导出图片,我需要canvas
的依赖。
注: 这个canvas
依赖不是很好装,如果大家装失败了,可以查看廖雪峰大佬的这个帖子学习下:
https://www.liaoxuefeng.com/article/937567769853440
现在万事具备,于是我们开始操作,我们打开命令行,准备开始一顿敲击。注意:以下环境是在Mac
下操作的
# 创建项目名称为TurnTextToImage mkdir TurnTextToImage && cd TurnTextToImage # 初始化一个npm项目 npm init -y # 安装Express依赖 npm install express --save # 安装Canvas的前置依赖 brew install pkg-config cairo pango libpng jpeg giflib # 安装canvas npm install canvas # 创建一个主文件 touch app.js
撰写代码
- 首先我们采用
Get
请求,因为Get
请求比Post
请求容易。而且Get
请求可以通过浏览器直接访问得到结果,不需要通过Postman
等其他工具,易于操作。对于Express
框架,拿到Get
请求中查询为Text
的数据可以通过如下方式:
// 假设请求参数中包含要转换的文字 const text = req.query.text;
举个🌰,对于localhost:3000/text=测试
的请求,我们的text
就是测试
- 然后我们使用
Canvas
,确定照片的长宽,在把我们的文字画出来即可。
const canvas = createCanvas(800 * 2, 600 * 2); const ctx = canvas.getContext("2d"); // 加入文本且让文本居中 ctx.fillText( text, (canvas.width - ctx.measureText(text).width) / 2, canvas.height / 2 );
- 最后将照片导出成流的形式,传给浏览器就可以啦。
// 将画布内容转为PNG格式的Buffer const imgBuffer = canvas.toBuffer("image/png"); // 设置HTTP响应头和发送图片Buffer res.set({ "Content-Type": "image/png", "Content-Length": imgBuffer.length, }); res.send(imgBuffer);
以下是所有的代码
const express = require("express"); const app = express(); const { createCanvas } = require("canvas"); // 注意请求的前缀是 /text-to-image app.get("/text-to-image", async (req, res) => { // 假设请求参数中包含要转换的文字 const text = req.query.text; // 创建画布和上下文 const canvas = createCanvas(800 * 2, 600 * 2); const ctx = canvas.getContext("2d"); // 设置背景色为黑色 ctx.fillStyle = "#000000"; // 黑色背景 ctx.fillRect(0, 0, canvas.width, canvas.height); // 设置字体样式并且绘制 ctx.font = "72px Microsoft YaHei"; ctx.fillStyle = "#ffffff"; // 白色文本 ctx.fillText( text, (canvas.width - ctx.measureText(text).width) / 2, canvas.height / 2 ); // 将画布内容转为PNG格式的Buffer const imgBuffer = canvas.toBuffer("image/png"); // 设置HTTP响应头和发送图片Buffer res.set({ "Content-Type": "image/png", "Content-Length": imgBuffer.length, }); res.send(imgBuffer); }); app.listen(3000, () => console.log("Server listening on port 3000"));
让我们通过node app.js
将服务起起来,然后在浏览器上输入即可看到效果
http://localhost:3000/text-to-image?text=【Node】一键生成博客标题图片
效果如下: