web实时长图实践( 二 )


由于安全限制,ios下跨域图片加属性也没法绕过跨域问题 。
2.crash
和一样,svg转图片后最终也是转传分享组件,超过500K可能导致的卡死和crash问题也存在 。
服务器端实现方案
开发:浏览器端的方案crash问题不能忍,不如在服务器端生成图片,传图片URL到分享组件?
本着最大限度复用代码的初衷,首选了无头浏览器截图的方案 。
是基于内核的无头浏览器,提供浏览器环境的命令行接口,我们可以进行网页截图、抓取网页数据等操作,更多详情可以去官网查看 。
安装时,注意安装以下依赖:
【web实时长图实践】sudo yum -y install gcc gcc-c++ make flex bison gperf ruby openssl-devel freetype-devel fontconfig-devel libicu-devel sqlite-devel libpng-devel libjpeg-devel
服务器端方案选择的是-node库,实现截图的核心代码如下
var sitepage = null; var phInstance = null; phantom.create().then(instance => {phInstance = instance;return instance.createPage();}).then(page => {let htm = ['','','','','','',''+ new Date() +'','',''].join("");page.property('content',htm);page.render('./test.png').then((err) => {phInstance.exit()}).catch(err => {phInstance.exit();})}).catch(error => {phInstance.exit();});
遇到的坑也不少,主要是环境问题:
1.没截图生成
开发:在mac上和上生成截图正常,部署到测试环境后不能生成截图,打印日志,没有明确的报错信息 。linux下权限问题?
查看和目录权限,没有写权限,修复权限问题,图片仍然不能生成 。
开发:字母命名的截图正常生成,不支持图片文件名包含数字?
一番验证,截图名包含数字-node不能正常生成图片文件 。
2.截图空白
开发:颜色和图案均能够渲染到截图中,只有文字不能渲染,字体有问题?
确认测试机中字体目录为空,更新字体,文字终于能正常渲染到截图中 。
3.截图模糊
又是模糊问题…
css使用相对rem单位,截图是设置缩放参数:
//csshtml{font-size: 100px;}.owner_avatar{width:.30rem;height: .30rem;border-radius: .30rem;margin-right: .10rem;}.events_img{width: .50rem;height:.50rem;}//phantomjs缩放处理page.property('viewportSize',{width:828,height:736});page.property('zoomFactor',2)page.property('content',htm);
4.截图加载慢
模糊问题设置2倍图后,图片大小暴涨到6M+,导致加载慢,设置截图质量:
page.render(fileName,{quality:85}).then((err) => {phInstance.exit();})
5.截图慢
生成一个最简单的截图,耗时2S左右,这个速度显然是不能接受的,暂时没找到比较好的优化方式 。
node
node 扩展了 API以提供与节点的接口,例如流式传输PNG数据,转换为实例等,更多介绍可以去node 官网查看 。
node 的环境搭建比较麻烦,依赖库与类似,这里就不列举了 。
绘制图片的核心代码:
const { createCanvas, loadImage } = require('canvas');const canvas = createCanvas(200, 200);const ctx = canvas.getContext('2d');ctx.font = '30px';ctx.fillText('test', 50, 100);loadImage('test.jpg').then((image) => {ctx.drawImage(image, 0, 0, 70, 70);})
node 与下面的方案对比,的性能更好,node 没再深入只实现了简单demo,踩坑不多 。