作者:诀九 前端名狮
转发链接:
https://mp.weixin.qq.com/s/BMg8bFUwa4gmm6v2acAe7Q
在头条发布文章时,需要为文章配置一个封面图片。我的常规做法就是网上搜一张图片,然后利用 Photoshop,在图片上加入文章标题,然后导出生成图片,如下图所示:
上图实际就是在一张背景图中,加入了一行文字。操作步骤简单,但是每次都需要打开PhotoShop修改文字,感觉麻烦、工作重复。
能不能用代码,解决日常生活中遇到的重复性工作呢?
整体思路:
文字和图形不能直接合并,需要将文字先转换成图形,然后再将图形进行合并,大致步骤如下:
分析实现:
1. 将文字转为SVG图形
将文字转换为SVG图形,需要借助Node的模块text-to-png,该模块能够将文字按照指定字体生成SVG图形。
SVG 意为可缩放矢量图形(Scalable Vector Graphics),放缩时不损失图形质量,SVG 是使用 XML 格式定义的图像,如下所示:
在html页面中嵌入了一个SVG表示三角形
<!DOCTYPE html>
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<path d="M150 0 L75 200 L225 200 Z" />
</svg>
</body>
</html>
展示效果:
SVG很好的充当了中间变量的角色,言归正传,看下代码如何实现转换:
let path = require('path');
let TextToSVG = require('text-to-svg');
let fontPath = path.join(__dirname, './fonts/msyhbd.ttf');//字体可以下载或者从本机系统内copy
let textToSVG = TextToSVG.loadSync(fontPath); // 加载字体文件
let options = {
x: 0, //文本开头的水平位置(默认值:0)
y: 0, // 文本的基线的垂直位置(默认值:0)
fontSize: 36, // 字体大小
anchor: 'top', // 坐标中的对象锚点
// letterSpacing: "", // 设置字母的间距
attributes: {
fill: '#FFFFFF' // 文字颜色
}
}
let textSVG = textToSVG.getSVG('【前端名狮】', options);
console.log(textSVG);
输出结果:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="72" height="47.513671875"><path fill="#FFFFFF"
d="M23.94 7.95L23.94 7.95L29.67 9.39Q28.65 10.65 27.54 11.92L27.54 11.92L35.40 11.92L35.40 16.07L0.56 16.07L0.56 11.92L8.03 11.92Q7.24 10.63 6.40 9.39L6.40 9.39L11.67 7.95Q13.03 9.98 14.22 11.92L14.22 11.92L21.36 11.92Q22.71 9.95 23.94 7.95ZM28.72 35.51L28.72 17.58L33.47 17.58L33.47 37.02Q33.47 39.39 32.43 40.71Q31.39 42.03 29.53 42.28Q27.67 42.54 22.85 42.54L22.85 42.54Q22.54 40.50 21.83 37.58L21.83 37.58Q25.03 37.72 26.68 37.72L26.68 37.72Q28.72 37.72 28.72 35.51L28.72 35.51ZM7.35 34.95L7.35 42.50L2.57 42.50L2.57 18L19.27 18L19.27 37.51Q19.27 39.80 18.21 41.01Q17.16 42.22 15.22 42.37Q13.29 42.52 10.58 42.54L10.58 42.54Q10.02 39.52 9.60 37.86L9.60 37.86Q12.27 38.00 12.76 38.00L12.76 38.00Q14.48 38.00 14.48 36.07L14.48 36.07L14.48 34.95L7.35 34.95ZM14.48 24.82L14.48 22.29L7.35 22.29L7.35 24.82L14.48 24.82ZM7.35 28.62L7.35 31.15L14.48 31.15L14.48 28.62L7.35 28.62ZM21.76 35.33L21.76 18.60L26.16 18.60L26.16 35.33L21.76 35.33ZM69.33 18.18L50.13 18.18L50.13 10.16L54.21 10.16L54.21 14.10L57.45 14.10L57.45 7.95L61.98 7.95L61.98 14.10L65.25 14.10L65.25 10.16L69.33 10.16L69.33 18.18ZM36.88 18.67L36.88 14.24L41.12 14.24Q39.96 11.44 39.02 9.63L39.02 9.63L43.17 7.98Q44.12 9.70 45.74 12.94L45.74 12.94L42.52 14.24L48.52 14.24L48.52 18.67L36.88 18.67ZM44.09 19.41L44.09 19.41L48.34 19.93L45.93 34.00L48.34 33.57Q48.20 34.70 48.02 38.00L48.02 38.00Q43.10 38.85 37.27 40.11L37.27 40.11L36.49 35.51L42.28 34.59Q43.28 27.35 44.09 19.41ZM36.91 20.18L40.71 19.55L42.54 32.27L38.64 32.94Q37.93 26.40 36.91 20.18L36.91 20.18ZM48.87 24.33L48.87 20.18L70.73 20.18L70.73 24.33L61.24 24.33L60.68 26.54L70.24 26.54L70.24 39.90Q70.24 41.75 69.06 42.29Q67.89 42.84 66.29 42.84L66.29 42.84Q65.13 42.84 63.95 42.64L63.95 42.64L63.72 40.89L60.64 40.89L60.64 30.69L58.64 30.69L58.64 40.89L55.20
40.89L55.20 30.69L53.19 30.69L53.19 42.64L49.04 42.64L49.04 26.54L56.30 26.54L56.76 24.33L48.87 24.33ZM66.09 37.97L66.09 30.69L64.09 30.69L64.09 38.74Q65.07 38.85 65.34 38.85L65.34 38.85Q66.13 38.85 66.09 37.97L66.09 37.97Z"/></svg>
2. 合并图形
用于合并图片的库有很多,比如gm、jimp、mapnik、sharp等,其中sharp是基于libvips库来实现的,性能是最高的,所以我采用了sharp来合并图形。
let textSVG = Buffer.from(textSVG);
let bgPath = path.join(__dirname, './img/bg.jpg');
let targetPath = path.join(__dirname, '../dist/bg.jpg');
sharp(bgPath).composite([{
input: textSVG,
gravity: 'center'
}]).toFile(targetPath);
sharp库注意事项
// 安装构建环境python、vc++
npm install --global --production windows-build-tools
// 安装node-gyp 编译工具
npm install --global node-gyp
// 安装sharp
npm install sharp
至此,我们就实现了一个简单的生成公众号封面图片的功能,让我们看看生成效果:
程序可以帮助我们干重复的事情,提高我们的生产力,如果程序员写的代码都用于解决自己生活中遇到的问题,对程序员无疑是巨大的动力源泉。