Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 709|回复: 0

vue中使用html2canvas及解决html2canvas截屏图片模糊问题

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-26 17:05:55 | 显示全部楼层 |阅读模式

    最近在项目中用到了html2canvas插件,遇到的一些坑写下来,与大家共勉。

    html2canvas  官方网站http://html2canvas.hertzen.com/index.html

    这是一个js截屏插件,在前台利用h5的canvas  将html的内容显示在canvas上,再利用 js 将canvas转化为图片

    1.vue 文件中引入 html2canvas.js

     1 <remote-script src="../html2canvas.js"></remote-script> 

    说明:src中的路径是html2canvas.js在项目中的路径

    remoteScript 标签是上篇博客定义的标签,详情见:http://www.cnblogs.com/zhuchenglin/p/7455203.html

    2.在vue中使用该插件,在methods中定义一个方法,内容为:

     1 setTimeout(function () {
     2   html2canvas(dom,{
     3         onrendered:function (canvas) {
     4           var image = new Image();
     5           image.src = canvas.toDataURL();
     6           document.getElementById('content_img').appendChild(image)
     7           dom.style.display='none'
     8        },
     9   });
    10 },0)

    这样就可以了

    说明:
    在方法中如果不加 setTimeout函数的话,虽然使用console输出的dom内容正常,但是如果在vue中定义的变量中的内容在canvas中显示不出来,可能与vue的声明周期有关,这个暂时不清楚,加上setTimeout函数之后,会将此函数中的操作加到处理队列末尾

    在拿到canvas后,转化为图片,直接就可以使用了。

     

     3.关于html2canvas截出来的图片模糊的问题,我查了好多资料,试了好多方法,最终找到一篇非常有用的文章 https://segmentfault.com/a/1190000007707209

    方法如下:

    (1.修改插件的源码

    <1.代码第999行renderWindow的方法中修改判断条件,增加一个options.scale存在的条件:

    将       

    1 if (options.type === "view") {
    2                 canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});
    3             } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {
    4                 canvas = renderer.canvas;
    5             } else {
    6                 canvas = crop(renderer.canvas, {width:  options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: 0, y: 0});
    7 
    8             }

    修改为     

     1 if (options.type === "view") {
     2                 canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});
     3             } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement) {
     4                 canvas = renderer.canvas;
     5             }else if(options.scale && options.canvas !=null){
     6                 log("放大canvas",options.canvas);
     7                 var scale = options.scale || 1;
     8                 canvas = crop(renderer.canvas, {width: bounds.width * scale, height:bounds.height * scale, top: bounds.top *scale, left: bounds.left *scale, x: 0, y: 0});
     9             }
    10             else {
    11                 canvas = crop(renderer.canvas, {width:  options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: 0, y: 0});
    12             }

    2.代码第 943 行 html2canvas 的方法中 修改width,height:

    1 return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {
    2     if (typeof(options.onrendered) === "function") {
    3         log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
    4         options.onrendered(canvas);
    5     }
    6     return canvas;
    7 });

    改为:

    1 width = options.width != null ? options.width : node.ownerDocument.defaultView.innerWidth;
    2 height = options.height != null ? options.height : node.ownerDocument.defaultView.innerHeight;
    3 return renderDocument(node.ownerDocument, options, width, height, index).then(function(canvas) {
    4     if (typeof(options.onrendered) === "function") {
    5         log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
    6         options.onrendered(canvas);
    7     }
    8     return canvas;
    9 });

    然后就可以使用了,将原来的使用放式稍微还一下就可以了,使用实例如下:

    在vue的方法中添加一个获取设备像素密度的方法 

    1  getPixelRatio(context){
    2      var backingStore = context.backingStorePixelRatio ||
    3              context.webkitBackingStorePixelRatio ||
    4              context.mozBackingStorePixelRatio ||
    5              context.msBackingStorePixelRatio ||
    6              context.oBackingStorePixelRatio ||
    7              context.backingStorePixelRatio || 1;
    8        return (window.devicePixelRatio || 1) / backingStore;
    9 },

    然后将最上面的使用示例改为:

     1   get_img(){
     2       let self = this;
     3       setTimeout(function () {
     4       var content_html = document.getElementById('content_html');    //要转化的div
     5       let width = content_html.offsetWidth;
     6       let height = content_html.offsetHeight;
     7       let offsetTop = content_html.offsetTop;
     8       let canvas = document.createElement("canvas");
     9       let context = canvas.getContext('2d');
    10       let scaleBy = self.getPixelRatio(context);
    11       canvas.width = width*scaleBy;
    12       canvas.height = (height+offsetTop)*scaleBy;
    13       context.scale(scaleBy,scaleBy);
    14       var opts = {
    15         allowTaint:true,//允许加载跨域的图片
    16         tainttest:true, //检测每张图片都已经加载完成
    17          scale:scaleBy, // 添加的scale 参数
    18          canvas:canvas, //自定义 canvas
    19          logging: true, //日志开关,发布的时候记得改成false
    20          width:width, //dom 原始宽度
    21          height:height //dom 原始高度
    22          };
    23      html2canvas(content_html,opts).then(function (canvas) {
    24        canvas.style.width = width+"px";
    25         canvas.style.height = height+"px";
    26         var image = new Image();
    27         image.src = canvas.toDataURL();
    28         document.getElementById('content_img').appendChild(image);      //将转化好的图片插入到防止图片转换的div中
    29         content_html.style.display='none'
    30      });
    31 }

    然后在html2canvas插件加载成功后调用get_img()方法即可将比较清晰的图片插入到指定位置 

    注:如需转载请注明出处:http://www.cnblogs.com/zhuchenglin/p/7455336.html

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-24 04:49 , Processed in 0.063575 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表