1

Node图片编辑工具gm和sharp

 1 year ago
source link: https://www.daguanren.cc/post/Node-tu-pian-bian-ji-gong-ju-gm-he-sharp.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Node图片编辑工具gm和sharp

我们经常会在微信上生成一些个性化的海报,海报中嵌入用户的微信头像和昵称,以及应用的二维码,如下两张海报:

*.png
*.png

下面先与大家分享如何在后台使用nodejs生成海报。

ps:在后台生成海报有好处也有坏处。相对于前端生成,好处是:由于服务器的配置统一,生成出的海报的尺寸一致,不会有变形的情况;坏处是:由于后台生成需要引入文字包,一般来说普遍不支持emoji表情符号。

先安装gm和sharp这两个图片处理包。

gm和sharp在linux上安装会有权限问题,需要手动创建文件夹。

或者使用如下命令安装:

npm install --unsafe-perm

安装部署方式参考之前的博客

https://www.daguanren.cc/post/promise_graphicsmagick.html

gm的下载地址:

https://sourceforge.net/projects/graphicsmagick/files/graphicsmagick/

以第一张海报图为例,我们讲解代码如何实现。

思路如下:

  • 先来直观的看下最终实现的效果图和所需的背景图,就可以大致知道我们要在哪些区域写入文字和拼接图片
*.png
*.png
// 引入用到的npm包,没安装的先npm install 安装const rp =require('request-promise');const gm = require('gm');const sharp = require('sharp');const fs = require('fs');// 定义请求参数const options = { method: 'GET', uri: img_url, // 头像或二维码地址 encoding: 'binary' // 或者也可以是 null// 发送请求let res = await rp(options);// 生成一串字符串来标记该头像是谁的let variable = think.uuid();// 将图片存到本地临时文件,存在了根目录下的tmp/img/文件夹下await fs.writeFileSync('tmp/img/avatar_'+variable +'.png', res, 'binary');// 头像和二维码均使用此方式存储到本地// 省略.....// 头像存储好了后,由于头像是正方形的,我们要将其改成圆形,并且调整其大小// 使用sharp将头像转成圆角 const roundedCorners = Buffer.from( '<svg><rect x="0" y="0" width="130" height="130" rx="65" ry="65"/></svg>' let sharpStream2 = sharp('tmp/img/avatar_'+ variable +'.png') .resize(130,130) .composite([{input:roundedCorners, blend: 'dest-in'}]) .png()// 将异步的sharpStream2.toFile函数封装下,改成同步let sharpWrite2 = think.promisify(sharpStream2.toFile, sharpStream2);// 将圆形头像存储到临时文件夹await sharpWrite2('tmp/img/circleAvatar_'+ variable +'.png');// 同理,可以对二维码做类似处理// 缩小二维码 let sharpStream = sharp(qrcode_local_path) .resize(193,193) .png() let sharpWrite1 = think.promisify(sharpStream.toFile, sharpStream); await sharpWrite1(qrcode_local_path_output);// 拼接图片和根据坐标点预估位置写入文字let stream = await gm() // 在(0,0)位置处放入背景图 .in('-page', '+0+0') .in(think.ROOT_PATH + '/www/static/image/poster/coupon_template.jpg') // 在(240,138)位置处放入圆形头像 .in('-page', '+240+138') .in('tmp/img/circleAvatar_'+ variable +'.png') // 在(327,987)位置处放入二维码 .in('-page', '+327+987') .in(qrcode_local_path_output) .mosaic() //写完赛日期 .fill('#ffffff') // 加载指定字体 .font("msyh.ttf") .fontSize(30) // 在指定位置写入名字 .drawText(387, 195, decodeURI(name)) // 写手机号 .fill('#ffffff') .font("msyh.ttf") .fontSize(30) .drawText(387, 240, decodeURI(phone)) // 写有效期 .fill('#ffffff') .font("msyh.ttf") .fontSize(20) .drawText(405, 887, decodeURI(coupon.validto.split(" ")[0])) // 保存最终的海报 let gmWrite = think.promisify(stream.write, stream); await gmWrite(qrcode_local_path_output);javascript

至此大功告成,当然代码并不是完整的,这里只是大致介绍。后面还有很多可以优化,例如可以将生成的海报保存下来,以便下次直接使用。下次生成海报的时候可以先判断之前是否已经生成了海报,如果已经生成了,那么直接从数据库把海报的url读取出来。

头像转圆形

https://zhuanlan.zhihu.com/p/137131729

带参二维码

https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html

在线免费生成条码:

https://barcode.tec-it.com/zh/?data=ZdPlSigNGrQl9CO4


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK