本次技术调研来源于H5项目中的一个重要功能需求:实现微信长按网页保存为截图。

这里有个栗子(请用微信打开,长按图片即可保存):3分钟探索你的知识边界

将整个网页保存为图片是一个十分有趣的功能,常见于H5活动页的结尾页分享。以下则是项目中调研和踩坑的一些小结和汇总。

一、实现HTML网页保存为图片

1.1 已知可行方案

现有已知能够实现网页保存为图片的方案包括:

方案1:将DOM改写为canvas,然后利用canvas的toDataURL方法实现将DOM输出为包含图片展示的data URI

方案2:使用html2canvas.js实现(可选搭配Canvas2Image.js实现网页保存为图片)

方案3:使用rasterizeHTML.js实现

1.2 解决方案的选择

方案1:需要手动计算每个DOM元素的Computed Style,然后需要计算好元素在canvas的大小位置等属性。

方案1难点:

相当于完全重写了整个页面的布局样式,增加了工作量。

由于canvas中是没有的对象概念,对于元素丰富、布局复杂的页面,不易重构

所有DOM元素改写进canvas会带来一些困难,例如:难以支持响应式,图片元素清晰度不佳和文字点击区域识别问题等。

方案2:该类功能中Github上stars最多(至今仍在维护),Stack Overflow亦有丰富的讨论。只需简单调用html2canvas方法并设定配置项即可。

方案3:该方案的限制较多,目前仅支持3类可转为canvas的目标格式: 页面url,html字符串和document对象。

小结: html2canvas是目前实现网页保存为图片功能的综合最佳选择。

1.3 html2canvas的使用方法

以下描述针对html2canvas版本是0.5.0-beta4

1.3.1 实现保存为图片的第一步:html转为canvas

基于html2canvas.js可将一个元素渲染为canvas,只需要简单的调用html2canvas(element[, options]);即可。下列html2canvas方法会返回一个包含有元素的promise:

html2canvas(document.body).then(function(canvas) {

document.body.appendChild(canvas);

});

1.3.2 实现保存为图片的第二步:canvas转image

上一步生成的canvas即为包含目标元素的元素对象。实现保存图片的目标只需要将canvas转image即可。

这里的转换方案有2种:

方案1:基于原生canvas的toDataURL方法将canvas输出为data: URI类型的图片地址,再将该图片地址赋值给元素的src属性即可

方案2:使用第三方库Canvas2Image.js,调用其convertToImage方法即可(GitHub)

实际上,Canvas2Image.js也是基于canvas.toDataURL的封装,相比原生的canvas API对于转为图片的功能上考虑更为具体(未压缩的包大小为7.4KB),适合项目使用。

二、实现高清截图的优化方案

2.1 基础的清晰截图优化方案

最终图片的清晰度取决于第一步中html转换成的canvas的清晰度。

现有解决方案参考;

其基本原理为:

将canvas的属性width和height属性放大为2倍(或者设置为devicePixelRatio倍),最后将canvas的CSS样式width和height设置为原先1倍的大小。

例如:希望在html中实际显示的宽高分别为160px,90px则可作如下设置

参考上述文档具体的使用案例如下;

convert2canvas() {

var shareContent = YourTargetElem;

var width = shareContent.offsetWidth;

var height = shareContent.offsetHeight;

var canvas = document.createElement("canvas");

var scale = 2;

canvas.width = width * scale;

canvas.height = height * scale;

canvas.getContext("2d").scale(scale, scale);

var opts = {

scale: scale,

canvas: canvas,

logging: true,

width: width,

height: height

};

html2canvas(shareContent, opts).then(function (canvas) {

var context = canvas.getContext('2d');

var img = Canvas2Image.convertToImage(canvas, canvas.width, canvas.height);

document.body.appendChild(img);

$(img).css({

"width": canvas.width / 2 + "px",

"height": canvas.height / 2 + "px",

})

});

}

2.2 进阶的清晰截图优化方案

上述设置可以解决通常的截图效果不清晰问题,不过探索还远没有结束。

实际在我们的项目中,即使作出2.1节的设置后,模糊成大果粒的渲染结果依然给清晰的幻想打了0分。

下面直接给出3条进一步的优化策略:

更改百分比布局为px布局(如果原先是百分比布局的话)

关闭canvas默认的抗锯齿设置

设置模糊元素的width和height为素材原有宽高,然后通过transform: scale进行缩放。这里scale的数值由具体需求决定。

基本原理

如果原来使用百分比设置元素宽高,请更改为px为单位的宽高,避免样式二次计算导致的模糊

默认情况下,canvas的抗锯齿是开启的,需要关闭抗锯齿来实现图像的锐化(MDN: imageSmoothingEnabled )

除了canvas可以通过扩大2倍宽高然后缩放至原有宽高来提高清晰度,对于DOM中其他的元素也可以使用css样式的scale来实现同样的缩放

例: html2canvas配置

convert2canvas() {

var cntElem = $('#j-sec-end')[0];

var shareContent = cntElem;//需要截图的包裹的(原生的)DOM 对象

var width = shareContent.offsetWidth; //获取dom 宽度

var height = shareContent.offsetHeight; //获取dom 高度

var canvas = document.createElement("canvas"); //创建一个canvas节点

var scale = 2; //定义任意放大倍数 支持小数

canvas.width = width * scale; //定义canvas 宽度 * 缩放

canvas.height = height * scale; //定义canvas高度 *缩放

canvas.getContext("2d").scale(scale, scale); //获取context,设置scale

var opts = {

scale: scale, // 添加的scale 参数

canvas: canvas, //自定义 canvas

// logging: true, //日志开关,便于查看html2canvas的内部执行流程

width: width, //dom 原始宽度

height: height,

useCORS: true

};

html2canvas(shareContent, opts).then(function (canvas) {

var context = canvas.getContext('2d');

context.mozImageSmoothingEnabled = false;

context.webkitImageSmoothingEnabled = false;

context.msImageSmoothingEnabled = false;

context.imageSmoothingEnabled = false;

var img = Canvas2Image.convertToJPEG(canvas, canvas.width, canvas.height);

document.body.appendChild(img);

$(img).css({

"width": canvas.width / 2 + "px",

"height": canvas.height / 2 + "px",

// 'border': '10px solid #000'

}).addClass('f-full');

$('#j-sec-end').remove();

});

}

例: DOM元素样式:

.targetElem {width: 54px;height: 142px;margin-top:2px;margin-left:17px;transform: scale(0.5)}

三、含有跨域图片的配置

由于canvas对于图片资源的同源限制,如果画布中包含跨域的图片资源则会污染画布,造成生成图片样式混乱或者html2canvas方法不执行等问题。

以下主要解决两类跨域的图片资源:包括已配置过CORS的CDN中的图片资源和微信用户头像图片资源。

3.1 针对CDN中的图片的配置

要求CDN的图片配置好CORS。CDN配置好后,通过chrome开发者工具可以看到响应头中应含有Access-Control-Allow-Origin的字段。

开启html2canvas的useCORS配置项。即作如下设置:

useCORS: true

}

html2canvas(element, options);

注意:

如果没有开启html2canvas的useCORS配置项,html2canvas会正常执行且不会报错,但是不会输出对应的CDN图片

(即在同一页面中,可测试同时包含CDN的图片和本地图片的资源的页面,但是只有本地图片能够被正常渲染出来)

3.2 针对微信用户头像的配置

如果需要将微信平台中的用户头像一并保存为图片,3.1的方案无能为力。可通过配置代理转发实现,此处不赘述。

其他注意事项

(1) margin的遮挡问题

微信中,唤出长按保存图片的菜单要求长按的对象直接是元素,如果元素上方存在遮挡,则不会唤出菜单。

而事实上,引发遮挡的并不只是非元素,还可能是margin属性。例如:若在页面底部,对一个绝对定位的元素设置了数值很大的margin-top,则margin-top所涉及的区域,均无法长按唤出菜单。解决方案:将margin-top改用为top即可。

(2) 安卓版微信保存图片失败的问题

canvas2img默认保存图片的格式为png,而在安卓版微信中所生成的图片尽管能长按唤出保存图片的菜单,但是无法正确保存到本地相册。 解决方案:设置canvas2img的生成图片格式配置项为jpeg即可。

(3) JPEG的黑屏问题

设置canvas2img输出格式为jpeg,会有一定几率导致生成的图片包含大量的黑色块。可能的解决方案:减小图片元素的体积大小和背景图片的尺寸大小。

(4) 不能保留动效

在图片的转化前,必须停止或者删除动效后才能正确渲染出图片,否则生成的图片是破裂的。

参考文献

h5跨域访问图片_网页保存为图片及高清截图的优化 | canvas跨域图片配置相关推荐

  1. 网页保存为图片及高清截图的优化 | canvas跨域图片配置

    本次技术调研来源于H5项目中的一个重要功能需求:实现微信长按网页保存为截图. 这里有个栗子(请用微信打开,长按图片即可保存):3分钟探索你的知识边界 将整个网页保存为图片是一个十分有趣的功能,常见于H ...

  2. 发字的楷书写法图片_优秀的楷体书写作品高清图片

    1 优秀的楷体书写作品高清图片 楷体是我国书法字体中的一种风格, 它对我国书法的发展有一定 的促进作用. 现如今, 一个优秀的楷体书法字体可以提高人们的字体 书写风格.下面是 整理的优秀的楷体书写作品 ...

  3. python页面转图片_网页转图片_技术分享 - SegmentFault 思否

    将一段文字转成图片,比如常用的长微博工具 这里用 PHP 来处理. text2pic composer require dsgygb/text2pic touch test.php require ' ...

  4. 电脑分辨率设置工具_干货分享:PPT 导出高清分辨率图片的四种方法

    PPT 不仅是办公神器,而且是科研作图的好工具. PPT 可以用来组图: 也可以绘制机制示意图: 以上都是我用 PPT 绘制出来的,今天不教大家怎么用 PPT 组图和绘制示意图,而是介绍从 PPT 中 ...

  5. 简笔画花边边框超简单_简单花边边框简笔画高清图片

    简笔画当中有些人想要画简单的花边图.你知道花边的简笔有哪些吗?今天先和学习啦小编一起欣赏这些简单花边边框简笔画高清图片,希望你会有所收获的. 简单花边边框简笔画高清图片欣赏 简单花边边框简笔画高清图片 ...

  6. 9个设计师都在用的图片素材网站,风格齐全,高清免费

    分享9个设计师都在用的图片素材以及制作海报工具,全部都是免费无版权,想找的纯背景图.商用图片素材.抠图等工具全部包括在内,再也不愁没图片素材资源. 一.免费高清图片素材网站 1.pixabay 一个非 ...

  7. python docx 合并文档 图片_使用python抓取大量简历文档内数据(word:docx;pdf;图片等)输出表格文件...

    1. 文章背景描述: 近期公司有员工离职了,技术岗位的. 让HR招人,招聘进度也太慢了,实在等不及,就撸起袖子自己上.(之前从来没招聘过) 自己在某招聘网站注册后,花了若干人民币,短时间收到大量求职者 ...

  8. 500万相机芯片尺寸_供应 500万像素 COMS芯片 高清图片效果真实性高 工业相机

    供应 500万像素 COMS芯片 高清图片效果真实性高 工业相机 型号:ke-510 色彩:彩色黑白可调 像素:500万像素 图像传感器:1/2.5寸coms传感器 白平衡:手动自动可调 工作温度:- ...

  9. qlaber 中放置图片_我准备了60个案例,教你彻底搞定PPT图片排版!

    大家好,我是秋小叶!这里是秋叶 PPT 的「Office 干货」栏目. 有图片的 PPT 页面该如何排版?这大概是很多小伙伴都头疼的一大难题~今天给你分享一篇三顿的文章,用 60 个案例教你彻底搞定 ...

最新文章

  1. R语言ggplot2可视化:使用热力图可视化dataframe数据、自定义设置热力图的颜色、自定添加标题、轴标签、热力图线框等
  2. Py之logging:logging的简介、安装、使用方法之详细攻略
  3. MySQL--字符集
  4. 兵团职称计算机准考证查询,兵团初级会计准考证打印入口官网
  5. 【转】ABP源码分析十:Unit Of Work
  6. idea安装activiti流程设计器_整合Activiti6.0流程设计器 | 字痕随行
  7. C++基础习题(计算三角形斜边)
  8. Ubuntu查看硬盘序列号
  9. 多个excel表格数据汇总如何完成
  10. 计算机常用英语关键词意思,英语关键词,英语关联词大全及翻译!
  11. java mysql 订单表设计
  12. 「项目管理」如何制定详细的项目计划?
  13. MarGo: Missing required environment variables: GOROOT GOPATH See the `Quirks` section of USAGE.md fo
  14. python语言是编译型语言-解释型语言与编译型语言
  15. 验证ssh免密登录_ssh无密码登录认证失败
  16. 年总结(六):半年历程总结(2016.6—2016.12)
  17. 【PV操作】南航重点:过独木桥
  18. python为什么被称为胶水语言_python为何称为胶水语言
  19. 机房收费系统——用户类型
  20. 用jQuery写开关灯案例

热门文章

  1. 下载yutube视频的方法 超方便
  2. 有插件有技巧,Sketchup牛人必备!
  3. xxl-job分布式任务调度中心部署实践(1)
  4. org.mapstruct:mapstruct 包的使用
  5. 论文阅读《Dense Relation Distillation with Context-aware Aggregation for Few-Shot Object Detection》
  6. Java实现解压缩文件和文件夹
  7. [理财日记] 简七小姐的理财日记(一)---教你省力地记账
  8. QQ概念版试用体会(转)
  9. 蛮牛手册之working in unity
  10. 计算机更新系统d盘东西还在吗,重装系统其他盘的东西还在吗_重做系统其它盘东西会丢失吗-win7之家...