当前位置: 首页 > news >正文

html2canvas.js 图片跨域 生成图片模糊 图片偏移 高清图的问题总结

首先 本人是一个canvas小白 基本不懂canvas的原理,拿到同事写的代码直接copy过来也没看文档(项目催的紧且文档是英文的) 话不多说 上代码 只是说出我的解决思路很多为什么还要花时间研究 比如canvas我都不会

<script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.min.js"></script>
复制代码
   html2canvas(document.querySelector(".upload_box")).then((canvas) => {
    
        var imgData = canvas.toDataURL('image/png');
      
        $('#save_img').html($('<div id="downLoadImg"><img src="' + imgData + '" alt=""></div>'));

    })
复制代码

如此简单是不是!获取dom 把返回的canvas转成图片显示! 遇到两个问题:

  • 部分图片没有生成
  • 生成的图片特别模糊(文字和图片都是模糊的)手机上更糊

可是为啥同事的代码没有问题呢!我拉来了同事 发现了一个问题:dom涉及到的图片不是本地的话 生成不出来 当时试了好多方法 都不行(这个时候傻逼的我为啥不去看看文档!)总之在网上试了很久 最终的做法是把从服务器获取的图片都转成base64显示 (网上找的代码) 暂时解决了

           getBase64: function getBase64(img) {//传入图片路径,返回base64
                function getBase64Image(img, width, height) {
                    var canvas = document.createElement("canvas");
                    canvas.width = width ? width : img.width;
                    canvas.height = height ? height : img.height;
                    var ctx = canvas.getContext("2d");
                    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
                    var dataURL = canvas.toDataURL();
                    return dataURL;
                }

                var image = new Image();
                image.src = img;
                image.crossOrigin = "Anonymous"
                var deferred = jQuery.Deferred();
                if (img) {
                    image.onload = function () {
                        deferred.resolve(getBase64Image(image));//将base64传给done上传处理
                    }
                    return deferred.promise();//问题要让onload完成后再return sessionStorage['imgTest']
                }
            },
            
复制代码
    _this.getBase64(resp.avatar)
    .then(function(base64){
    // console.log(base64);
        $('.user_info .user_head img').attr('src',base64)
    },function(err){
        console.log(err);
    });
复制代码

模糊我都不想处理了 !但是产品说不行啊,你这个生成的图片二维码都识别不出来 必须要清晰 就在我加班到早上六点也解决不了的时候 产品说可以先隐藏这个功能,花时间研究一下。 于是第二天 我就开始准备找方法了。

首先把官方文档看了一遍:html2canvas.hertzen.com/configurati… 虽然是英文 但其实没多少东西 主要就是参数配置 一句句谷歌也能翻译出来(不要被英文吓到)

看到了一个配置:useCORS false Whether to attempt to load images from a server using CORS 不就是允许跨域获取图片吗,为什么之前试了这句好像没有效果呢?

                         var opts = {
                                useCORS: true
                            };
                            
复制代码
   html2canvas(document.querySelector(".upload_box"),opts).then((canvas) => {
    
        var imgData = canvas.toDataURL('image/png');
      
        $('#save_img').html($('<div id="downLoadImg"><img src="' + imgData + '" alt=""></div>'));

    })
复制代码

酱紫 远程的图片页也可以了 不会出现空白页!真是开心,比转成程base64方便多了 毕竟好几张图片都要转很麻烦(后面还有一个转化的大坑我这里没遇到,也是雷 后面会说) 而且转化之后的图片会更加不清晰!开心!

然后我就开始我的漫长的 研究怎么生成清晰图的探索之路了!(找到同事的代码,他啥都没有配置啊! 然后我发现html2canvas默认生成的canvas的宽高就是你dom结构的宽高 同事的代码截图的是整个网页 很大 生成的图片也就挺清晰的 ,但是我的截图模块只占网页不到1/2 太小了! 感觉就是这个原因,我开始想要说复制一个dom吧尺寸放大 但是觉得太low了 于是还是想尝试一下别的!

当然能百度到很多

  • 最多的就是修改源码 技术很渣的我直接放弃了 不会改不敢改
  • 然后修改配置项啊 反正按照他们的说的方法
    var width = $('.upload_box').width()
    var height = $('.upload_box').height()
    var canvasBox = document.createElement("canvas"); 
    var scale = window.devicePixelRatio; 
    canvasBox.width = width * scale; 
    canvasBox.height = height * scale; 

    canvasBox.style.width = width + "px";
    canvasBox.style.height = height + "px";
    canvasBox.getContext("2d").scale(scale, scale); 
   // 获取元素相对于视窗的偏移量
   var opts = {
        scale: scale, 
        useCORS: true,
    };
复制代码

差不多都是这样的写法 但是但是出来canvas是清晰了!但是不居中啊 尝试在配置项中增加参数 x y偏移 但是并没有什么用 然后我就想 程序员怎么能用百度 !遂换谷歌 终于在 知乎里面看到一个好像比较看不懂的写法 于是就试试: www.zhihu.com/question/48…

作者:PajamaCat
链接:https://www.zhihu.com/question/48217555/answer/283209866
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

前面的回答没有解决margin导致的生成图片偏移问题, 这里是解决方法:      var dom = $('#to-save-img')
      var width = dom.width();
      var height = dom.height();
      var type = "png";
      var scaleBy = 2; //缩放比例
      var canvas = document.createElement("canvas");
      // 获取元素相对于视窗的偏移量
      var rect = dom.get(0).getBoundingClientRect(); 
      canvas.width = width * scaleBy;
      canvas.height = height * scaleBy; 
      canvas.style.width = width * scaleBy + "px";
      canvas.style.height = height * scaleBy + "px";
      var context = canvas.getContext("2d");
      context.scale(scaleBy, scaleBy);
      // 设置context位置, 值为相对于视窗的偏移量的负值, 实现图片复位
      context.translate(-rect.left,-rect.top);
复制代码

就是这个所谓的偏移,我一看我要截图 dom的确是margin:0 auto的 是相对居中的 所以试试

           var width = $('.upload_box').width()
                var height = $('.upload_box').height()
                var canvasBox = document.createElement("canvas"); 
                var scale = window.devicePixelRatio; 
                var rect = $('.upload_box').get(0).getBoundingClientRect(); 
                canvasBox.width = width * scale; 
                canvasBox.height = height * scale; 

                canvasBox.style.width = width + "px";
                canvasBox.style.height = height + "px";
                canvasBox.getContext("2d").scale(scale, scale); 
                canvasBox.getContext("2d").translate(-rect.left, -rect.top); 
                           // 获取元素相对于视窗的偏移量
                           var opts = {
                                scale: scale, 
                                canvas: canvasBox, 
                                // logging: true, 
                                // width: width*2, 
                                // height: height*2 ,
                                // allowTaint:true,
                                useCORS: true,
                                // x:-200,
                            };
复制代码

然后真的就好了!!!!!!! 激动啊激动啊简直大神啊!

然后我就很开心了 开心的发给测试 然后扑街 测试的手机上还是完全白板 啊?难道是兼容性的问题?可是我们都是iphone7啊 ! 而且兼容性什么的最讨厌了! 我快绝望了 然后在我的手机上登陆她的账号 也是截图不了的 这太奇怪了 !难道是账号的问题? 毕竟一整天都在解决所谓的跨域问题!图片跨域啥的很多啊!

然后果然 她的账号的微信头像 : wx.qlogo.cn/mmopen/vi_3…

对这里就是我之前说到的转base64的坑 微信的头像不允许跨域,所以html2canvas无法直接使用微信的头像生成canvas,所以啊 我就想本地base64就好了 就一个头像,但是

查了一下是:污染的画布无法输出,发现原来是受限于 CORS 策略,会存在跨域问题,虽然可以使用图像(比如append到页面上)但是绘制到画布上会污染画布,一旦一个画布被污染,就无法提取画布的数据,比如无法使用使用画布toBlob(),toDataURL(),或getImageData()方法;当使用这些方法的时候 会抛出一个安全错误

所以 我就妥妥的把问题丢给后端 让他们把微信头像转成base64给我了! 完全搞定了!撒花

写下这个记录帖 虽然问题暂时解决了 但是还有更多的不懂在等着我去看

转载于:https://juejin.im/post/5b74ebe7518825293b19cf1f

相关文章:

  • 人生苦短我用python(03),如何调试python程序
  • Django 框架07: 状态保持
  • 分类解析
  • 直播中 BarrageRenderer 弹幕的显示
  • linux学习之路:2.基本指令(2)
  • Discuz 配置tag标签页面url静态化(nginx)
  • [BZOJ] 1001: [BeiJing2006]狼抓兔子
  • 机器学习 vs. 深度学习
  • 请碟仙儿│一个区块链思想实验
  • JavaScript-Array类型
  • Jmeter压力测试、操作数据库、断言、分布式压测(添加负载机)学习笔记
  • oracle 修改字符集
  • iOS持续集成(一)——fastlane 使用
  • Python tips(
  • C#窗体越界时鼠标还能回到初始坐标位置
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • #Java异常处理
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • avalon2.2的VM生成过程
  • canvas 高仿 Apple Watch 表盘
  • css属性的继承、初识值、计算值、当前值、应用值
  • HashMap ConcurrentHashMap
  • java多线程
  • Java精华积累:初学者都应该搞懂的问题
  • Puppeteer:浏览器控制器
  • React 快速上手 - 07 前端路由 react-router
  • 讲清楚之javascript作用域
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 七牛云假注销小指南
  • hi-nginx-1.3.4编译安装
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • # 安徽锐锋科技IDMS系统简介
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • (1)虚拟机的安装与使用,linux系统安装
  • (Java)【深基9.例1】选举学生会
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (过滤器)Filter和(监听器)listener
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (实战篇)如何缓存数据
  • (已解决)什么是vue导航守卫
  • (转)项目管理杂谈-我所期望的新人
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .net core 连接数据库,通过数据库生成Modell
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .net连接oracle数据库
  • ?php echo ?,?php echo Hello world!;?
  • @Autowired多个相同类型bean装配问题
  • @RequestBody的使用
  • @transaction 提交事务_【读源码】剖析TCCTransaction事务提交实现细节
  • [2019.3.20]BZOJ4573 [Zjoi2016]大森林
  • [AIGC] SQL中的数据添加和操作:数据类型介绍