最近在工作上有一个需求是在 server(node.js), 将几张图片和文字合成
经过 google 一番, 尝试了 3 个库:
node-images: 国人开发的一个轻量级, 不需要额外安装依赖的图片处理库可以实现图片大小, 合并等功能本打算使用它来完成需求不过已经近一年不维护了 node 8.x 版本跑步起来看了一下 issue, 发现各个平台系统的兼容性堪忧还是不去踩这个坑了另外其也不支持文字写入
node-canvas: 功能很强大, 搜到不少 Demo, 没有做深入调研应该是可以实现需求
终于到了重点: gmnodeJs 对 GraphicsMagick 和 ImageMagick 的封装图片处理的老牌工具, 包含各种各样的功能由于两个工具本身都不是 js 实现, 所以需要额外安装这里就主要说说 gm
install:
在安装 gm 之前, 我们需要安装 GraphicsMagick 和 ImageMagick
mac 这里:
- brew install imagemagick
- brew install graphicsmagick
linux 的话, 拿 apt-get 安装就 ok
这两个安装完毕之后在工程目录:
npm i gm --save
就 ok
usage:
我们现在想把图一 (test.jpg)(600*600) 的右下角添加图二(1.jpg)(140*140), 使其合成一张图
这里 我们使用 gm 的 draw 方法
- const gm = require('gm')
- gm('./test.jpg')
- .draw('image Over 460, 460, 140, 140"./1.jpg"')
- .write(`./output/${Date.now()}.jpg`, function(err) {
- if (!err) {
- console.log('done')
- }else {
- console.log(err.message || "出错了!");
- }
- })
跑一下程序, output 目录下就多出来一张合成的照片咯当然 gm 还有很多种合成照片的方式:
compose/mosaic/append(api 文档说的很细致这里就不展开了)
gm 的 APi 文档地址是: gm api 文档
图片和图片合成很简单之后我们还想添加一段文字, 查阅 api 我们发现有这个方法: drawText
.drawText(x, y, text [, gravity])
如果没有 gravity 参数, 那么就将 text 绘制到图片中的 (x,y) 坐标处
如果带有 gravity 参数, 从 (x,y) 坐标开始到右下角构成的图片范围内, 依据 gravity 含义绘制文字
gravity 的选项如下:
- NorthWest, North, NorthEast, West, Center, East, SouthWest, South, or SouthEast
- gm('./test.jpg')
- .draw('image Over 460, 460, 140, 140"./1.jpg"')
- .drawText(100, 100, 'wa~~~')
- .write(`./output/${Date.now()}.jpg`, function(err) {
- if (!err) {
- console.log('done')
- }else {
- console.log(err.message || "出错了!");
- }
- })
上述代码, 我们想要在图片 左上为 (0,0)(100,100) 的位置添加 wa~
跑一下这是报了一个错:
Error: unable to read font `/usr/local/share/ghostscript/fonts/n019003l.pfb'@ error/annotate.c/RenderFreetype/1123: `(null)'
这是因为我们没有装 ghostscript(一套建基于 AdobePostScript 及可移植文档格式 (PDF) 的页面描述语言等而编译成的免费软件)
brew install ghostscript
安装好了在执行就 ok 了
顺势我们再试试中文
.drawText(100, 100, '哇~~~')
乱码了 google 一下发现 gmGraphicsMagick 的使用中, 中文乱码问题屡见不鲜
解决方案总结起来就是 1)utf-8 编码; 2)要指定中文字体库
这里我们下载了微软雅黑的 ttf 文件, 放在根目录的 font 文件夹下. 我们再添加一些字体属性:
- gm('./test.jpg')
- .draw('image Over 460, 460, 140, 140"./1.jpg"')
- .drawText(100, 100, '哇')
- .fontSize(36)
- .fill('#fff')
- .font('./font / 微软雅黑. ttf')
- .write(`./output/${Date.now()}.jpg`, function(err) {
- if (!err) {console.log('done')}else{
- console.log(err.message || "出错了!");
- }
- })
这样 白的的 36 号字的哇就出现在了图片上
来源: https://juejin.im/entry/5aa2c21df265da23a334d40f