web实时长图实践( 三 )



是一套功能强大、稳定而且免费的工具集和开发包,可以用来读、写和处理超过90种的图片文件,包括流行的TIFF、JPEG、GIF、 PNG、PDF以及等格式 。
可以根据web应用程序的需要动态生成图片, 还可以对一个(或一组)图片进行改变大小、旋转、锐化、减色或增加特效等操作,并将操作的结果以相同格式或其它格式保存,对图片的操作,即可以通过命令行进行,也可以用C/C++、Perl、Java、PHP、或Ruby编程来完成 。更多详情可在官网查看 。
是从5.5.2 分支出来的,据说它变得更稳定和优秀,更多详情可在官网查看 。
看起来是更好的选择,但是由于node gm这个库没有实现的半透明和圆角支持,而且针对专辑的大事件长图做了一些性能对比两者差异不大,所以选择使用 。
node gm切换的方式非常简单,只要加以下设置:
var gm = require('gm');var imageMagick = gm.subClass({ imageMagick: true });
不可避免的,使用也遇到一些坑:
1.半透明遮罩

web实时长图实践

文章插图
设计:专辑封面背景使用白透明遮罩,遮罩的颜色根据封面图来定,深色封面图用白色文字,浅色封面图用黑色文字 。
开发:OK,先获取封面图颜色信息,再判断颜色深浅
//RGB与YUV互转,Y>=128 为浅色Y'= 0.299*R' + 0.587*G' + 0.114*B'U'= -0.147*R' - 0.289*G' + 0.436*B' = 0.492*(B'- Y')V'= 0.615*R' - 0.515*G' - 0.100*B' = 0.877*(R'- Y')R' = Y' + 1.140*V'G' = Y' - 0.394*U' - 0.581*V'B' = Y' + 2.032*U'//ImageMagick设置透明色.fill("rgba(0,0,0,.5)")
2.头像圆角
web实时长图实践

文章插图
设计:这些头像要用圆角哦 。
开发:OK(还好支持圆角)
.fill("avatar.jpg").drawCircle(80,120,30,120)
圆角图片实现方式与类似,画一个圆,然后用头像图片去填充来实现头像圆角 。
3.昵称emoji表情
web实时长图实践

文章插图
绘制昵称中的表情图比较麻烦,使用支持emoji的字体,尝试过的彩色emoji字体,但是有BUG,不能还原为彩色的 。
最终解决方案:
1)使用等宽字体,方便计算精确的emoji位置
2)绘制昵称中的表情图片
.draw("image Over " + size + " " + url)
性能优化:
优化前:
web实时长图实践

文章插图
优化后:
web实时长图实践

文章插图
生成单张图片耗时100ms左右,但是并发请求多了平均耗时就暴涨到3S+,这个速度显然是不能接受的,经过一番优化后将平均耗时降到1S左右,主要优化点如下:
1.gm代码拼接,VM中执行
多次调用gm多次操作图片,严重影响性能,将图片操作代码拼接成字符串,在VM中执行,只调用一次gm,核心代码如下:
let sandbox = {gm : imageMagick,start : Date.now()}//计算图片高度let offset = getOffset();let qrcodeStr = getQrcodeStr();let titleStr = (function(){return ['.fontSize(24)','.fill("gray")','.drawText(164,152,"我是标题")'];})();let str = 'gm(828,'+ offset.height +',"#fff").font("'+ FONTS +'",48)'+ titleStr + qrcodeStr +'.quality(90).write("test.jpg",function(err){console.log(err || Date.now() - start)})';let script = new vm.Script(str);let context = vm.createContext(sandbox);script.runInContext(context);