实现网页页面截屏,并且将其转换为指定图片格式保存下来,需要使用到html2canvas.js。

前面是实现原理和步骤分析,具体实现代码在文章尾部。

一、实现HTML页面截屏并保存为图片

原理是遍历需要转换的页面DOM元素,然后通过html2canvas.js将其转换为canvas标签画布,然后使用Canvas2Image.js控件的convertToImage方法(也可以使用canvas的toDataURL方法),将canvas转换为img标签,然后获取其src值(base64编码),实现将网页保存图片。

html2canvas.js:https://github.com/niklasvh/html2canvas/

Canvas2Image.js:https://github.com/hongru/canvas2image


第一步:html标签转换为canvas

基于html2canvas.js可以将一个元素渲染为canvas,那如果我们只需要对页面中囊括了所有元素的最大的元素(如最大的div)进行转换即可,这样下面的所有元素都会一齐转换。

只需要调用html2canvas(element[, options])即可,下列html2canvas方法会返回一个包含有<canvas>元素的`promise‘:

html2canvas(document.body).then(function(canvas) {document.body.appendChild(canvas);
});
第二步:canvas转化为image

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

这里有两种转换方法:

  1. 基于原生canvas的toDataURL方法将canvas输出为data:URI类型的图片地址,再将该图片地址赋值给< image>元素的src属性,然后通过< a>标签进行下载。
  2. 使用第三方库Canvas2Image.js,调用其convertToImage方法,转换为img标签,再通过标签进行下载。

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


二、生成图片的清晰度优化方案

1.基础的清晰度优化方案

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

基本原理为:

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

2.进阶的清晰度优化方案

在上一步的设置后,大果粒一般的渲染结果依然没有什么好的方法。

所以下面有三条进阶优化的方法:

  1. 更改百分比布局为px布局(如果原先是百分比布局的话)
  2. 关闭canvas默认的抗锯齿设置
  3. 设置模糊元素的width和height为素材原有宽高,然后通过transform:scale进行缩放。这里的scale的数值由具体需求决定

基本原理为:

  1. 如果原来使用百分比设置元素宽高,更改为px为单位的宽高,避免样式二次计算导致的模糊
  2. 默认情况下,canvas的抗锯齿是开启的,需要关闭抗锯齿来实现图像的锐化
  3. 除了canvas可以通过扩大2倍宽高然后缩放至原有宽高来提高清晰清晰度,对于DOM中其他元素也可以使用css样式的scale来实现同样的缩放

例如:DOM元素样式:

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

三、含有跨域图片的配置(解决跨域图片的问题)

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

以下主要解决两类跨域的图片资源:包括已配置过的CORS的CDN(分布式缓存服务器)中的图片资源和微信用户头像图片资源。

1.针对CDN中的图片的配置
  1. 要求CDN的图片配置好CORS,CDN配置好后,通过chrome开发者工具可以看到响应头中应含有Access-Control-Allow-Origin的字段。
  2. 开启html2canvas的useCORS配置项,即作如下设置:
var opts = {useCORS: true};html2canvas(element, opts);

注意:

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

(例如:同事包含CDN的图片和本地图片的资源的页面,但是只有本地图片能够被正常的渲染出来)

2.针对微信用户头像的配置

如果要将微信平台中的用户头像一并保存为图片,可通过配置服务端代理转发(forward)实现。


四、其他注意事项

1.JPEG的黑屏问题

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

2.不能保留动效

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


根据上述步骤,具体的实现代码案例如下:

1.基于html2canvas.js和Canvas2Image.js:
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><title>截屏并保存</title><script type="text/javascript"src="C:\Users\Administrator\Desktop\jquery-ui-1.11.4和jQuery-3.4.0.custom\jquery-3.4.0.min.js"></script><script type="text/javascript" src="C:\Users\Administrator\Desktop\html2Canvas\html2canvas.js"></script><script type="text/javascript" src="C:\Users\Administrator\Desktop\canvas2image-master\canvas2image.js"></script><script>function convert2canvas() {var shareContent = document.getElementById("dialog1"); //获取囊括所有元素的最大的div元素var width = shareContent.offsetWidth; //获取dom宽度(包括元素宽度、内边距和边框,不包括外边距)var height = shareContent.offsetHeight; 获取dom高度(包括元素高度、内边距和边框,不包括外边距)var canvas = document.createElement("canvas"); //创建一个canvas标签元素var scale = 2; //定义放大倍数,可以支持小数var imgType = "image/jpg";//设置默认下载的图片格式canvas.width = width * scale; //定义canvas宽度 * 倍数(图片的清晰度优化),默认宽度为300pxcanvas.height = height * scale; //定义canvas高度 * 倍数,默认高度为150pxcanvas.getContext("2d").scale(scale,scale); //创建canvas的context对象,设置scale,相当于画布的“画笔”拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法var opts = { //初始化对象scale: scale, //添加的scale参数canvas: canvas, //自定义canvaslogging: true, //日志开关,便于查看html2canvas的内部执行流程width: width, //dom的原始宽度和高度height: height,useCORS: true //开启html2canvas的useCORS配置,跨域配置,以解决图片跨域的问题};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.convertToImage(canvas, canvas.width, canvas.height,imgType); //将绘制好的画布转换为img标签,默认图片格式为PNG.document.body.appendChild(img); //在body元素后追加的图片元素至页面,也可以不追加,直接做处理$(img).css({ //设置图片元素的宽高属性"width": canvas.width / 2 + "px","height": canvas.height / 2 + "px",})$(img).attr("id", "img1"); //为图片元素添加id属性// 生成一个a超链接元素var a = document.createElement('a');// 创建一个单击事件var event = new MouseEvent('click');// 将a的download属性设置为我们想要下载的图片名称,若name不存在则使用‘下载图片名称’作为默认名称a.download = name || '下载图片名称';a.href = img.src;//将img的src值设置为a.href属性,img.src为base64编码值// 触发a的单击事件a.dispatchEvent(event);});}</script></head><body><div id="dialog1" title="离职指引"><p><a href="" style="display: block;text-align: center;" id="downloadImg" download="downImg">点击下载图片</a></p></br><p> 以前我们只能通过其他的截图工具来截取图像。现代浏览器的功能已经越来越强,随着H5的逐渐普及,浏览器本身就可以截图啦。html2canvas就是这样一款前端插件,它的原理是将Dom节点在Canvas里边画出来。虽然很方便,但有以下限制</p><p> 以前我们只能通过其他的截图工具来截取图像。现代浏览器的功能已经越来越强,随着H5的逐渐普及,浏览器本身就可以截图啦。html2canvas就是这样一款前端插件,它的原理是将Dom节点在Canvas里边画出来。虽然很方便,但有以下限制</p><p> 以前我们只能通过其他的截图工具来截取图像。现代浏览器的功能已经越来越强,随着H5的逐渐普及,浏览器本身就可以截图啦。html2canvas就是这样一款前端插件,它的原理是将Dom节点在Canvas里边画出来。虽然很方便,但有以下限制</p><p> 以前我们只能通过其他的截图工具来截取图像。现代浏览器的功能已经越来越强,随着H5的逐渐普及,浏览器本身就可以截图啦。html2canvas就是这样一款前端插件,它的原理是将Dom节点在Canvas里边画出来。虽然很方便,但有以下限制</p><p> 以前我们只能通过其他的截图工具来截取图像。现代浏览器的功能已经越来越强,随着H5的逐渐普及,浏览器本身就可以截图啦。html2canvas就是这样一款前端插件,它的原理是将Dom节点在Canvas里边画出来。虽然很方便,但有以下限制</p><p> 以前我们只能通过其他的截图工具来截取图像。现代浏览器的功能已经越来越强,随着H5的逐渐普及,浏览器本身就可以截图啦。html2canvas就是这样一款前端插件,它的原理是将Dom节点在Canvas里边画出来。虽然很方便,但有以下限制</p><input type="button" onclick="convert2canvas();" value="截图并下载"></br></div></br></body></html>
2.基于canvas原生的通用截屏保存方法:
  <script>//dowloadImg($('#img'),"下载图片")function downloadImg(selector, name) { //通用图片保存下载方法,将页面的img标签保存为图片格式var image = new Image();// 解决跨域 Canvas 污染问题image.setAttribute('crossOrigin', 'anonymous');image.onload = function () {//图片元素完成后触发事件var canvas = document.createElement('canvas')//创建一个canvas标签元素canvas.width = image.width;canvas.height = image.height;var imgType = "image/png";//设置默认下载的图片格式var context = canvas.getContext('2d');//设置canvas,context属性,获取“画笔”context.drawImage(image, 0, 0, image.width, image.height);//绘制图片var url = canvas.toDataURL(imgType);//将图片转换为base64编码// 生成一个a元素var a = document.createElement('a');// 创建一个单击事件var event = new MouseEvent('click');// 将a的download属性设置为我们想要下载的图片名称,若name不存在则使用‘下载图片名称’作为默认名称a.download = name || '下载图片名称';// 将生成的URL设置为a.href属性a.href = url;// 触发a的单击事件a.dispatchEvent(event);}image.src = document.querySelector(selector).src;//将img标签的src值赋给image对象的src值。}</script>

使用html2canvas完成页面截屏并保存为图片相关推荐

  1. html2canvas 浏览器端截屏并下载保存(兼容IE)

    html2canvas 浏览器端截屏并下载保存(兼容IE) <!DOCTYPE html> <html> <head> <meta charset=" ...

  2. swift 将图片保存到本地_Swift实现截屏并保存相册

    func saveToLocal() { //截屏 let screenRect = UIScreen.mainScreen().bounds UIGraphicsBeginImageContext( ...

  3. 如何使用ChromeHeadLess 技术实现后台对前台页面截屏

    如何使用ChromeHeadLess 技术实现后台对前台页面截屏 1 chrome headless 1.1 什么是chrome headless 1.2 chrome headless的作用 1.3 ...

  4. 【java-调用摄像头进行截屏与保存-实例篇1-0716】

    java-调用摄像头进行截屏与保存-实例篇1-0716 一. 主要涉及功能 二. 主要涉及技术 三. 开启摄像的Webcam包导入IDEA 四.多线程入门 4.1为什么用线程 4.2 如何打开一个新的 ...

  5. JAVA服务端实现页面截屏(附代码)

    JAVA服务端实现页面截屏 适配需求 方案一.使用JxBrowser 使用步骤: 方案二.JavaFX WebView 使用步骤: 方案三.Headless Chrome 使用步骤: 综上方案对比 记 ...

  6. 使用Snagit安安静静的截屏并保存

    使用Snagit软件安安静静的截屏并保存需要注意两点. 1.关闭在编辑器预览. 2.打开分享--文件. 图片.png 设置好之后保存预设.并设置快捷键.这样在工作或者网游戏过程中就可以快速的截屏并保存 ...

  7. Unity iOS 获取相册图片, 调用原生相机, 截屏并保存到相册

    原文链接 该Demo实现如下功能 1.从相册_照片 获取图片, 并贴在Image上 2.从相册_时刻 获取照片, 并贴在Image上 3.打开原生相机,拍照并把照片贴在Image上 4.截屏并保存到相 ...

  8. ios——如何完成截屏操作并将截屏结果保存到设备本地相册

    ios工程--(UIView)获取设备相册权限截取屏幕内容并保存到设备本地相册 设备/引擎:Mac(11.6)/cocos 开发工具:Xcode(13.0) 开发需求:对某个玩法进行截屏操作,并以图片 ...

  9. 将WebBrowser中的页面截屏保存为图片

    先说一点题外话,将WEB页面渲染成图片有比较好的开源工具,如CutyCapt ,它使用WebKit渲染,兼容多种操作系统,适合于在服务器上作为后台服务运行. 不过,这里说到的是对WebBrowser内 ...

最新文章

  1. 项目进度管理:定义活动
  2. 每天一道LeetCode-----计算给定范围内所有数的与运算结果
  3. 分享成功 用心经营就会结出果实(转)
  4. macos必做的设置_如何在MacOS上设置PHP,CaddyServer和Kirby —以及为什么要这样做
  5. executable file and DLL
  6. 面试—每日一题(4)
  7. 深入了解微服务的优点与缺点
  8. Django 【第十四篇】信号
  9. Linux下MongoDB服务安装
  10. Android应用程序反编译
  11. 线性代数及其应用(part2)--特征方程
  12. Spring Batch之Job级拦截器实现(四)
  13. python双人贪吃蛇游戏
  14. php动态网站实训心得体会,十天学会写PHP动态网站
  15. python七巧板房子_七巧板拼图技巧,房子用简单的七巧板怎么拼 请给图
  16. 微生物组-扩增子16S分析第10期(线上/线下同时开课,本年最后一期)
  17. chemdraw怎么画拐弯的箭头_怎么样绘制弧形箭头?
  18. 重装系统后电脑图片显示不出来怎么办
  19. ASR项目实战-交付团队的分工
  20. 【转】Swagger详解(SpringBoot+Swagger集成)

热门文章

  1. 疯狂劲爆物理游戏《卡车大战骷髅》
  2. mybatis中aplication.properties配置
  3. 加勒比中央银行正探索发行央行数字代币
  4. PyOpenCV图像逆时针旋转90度
  5. 升序降序图标显示html,表格升序降序.html
  6. 谷歌seo文案写作:掌握技巧,靠文章也能开启流量池
  7. python能做射击类游戏吗_python能做游戏吗
  8. JavaScript日期相关计算
  9. 一些做扫描识别的第三方控件
  10. 标称电阻值(转) 常用的5%和1%精度电阻的标称值