web前端生成图片之探索踩坑
前段时间,产品和运营整了个非常变态的需求,要求将一个活动页面输出为图片,然后用户进行分享
开始以为是用户自己手动截图分享,没想到后来不是,细思极恐,感叹需求之变态。
从网上找了N个方案,最后确定使用 html2canvas 基本可实现(http://html2canvas.hertzen.com/),下面开始踩坑。
html2canvas 的原理在于利用封装的js将html的显示输出转化为canvas,根据页面的复杂度,可能会遇到一些问题。
截图模糊
解决原理就是讲canvas画布的width和height放大两倍
后来了解canvas的时候,其写法不同于css的宽高设置,因为css里的只是展示画布显示的大小,不像canvas是真正的图画分辨率的大小
1 /*图片跨域及截图模糊处理*/ 2 let shareContent = domObj,//需要截图的包裹的(原生的)DOM 对象 3 width = shareContent.clientWidth,//shareContent.offsetWidth; //获取dom 宽度 4 height = shareContent.clientHeight,//shareContent.offsetHeight; //获取dom 高度 5 canvas = document.createElement("canvas"), //创建一个canvas节点 6 scale = 2; //定义任意放大倍数 支持小数 7 canvas.width = width * scale; //定义canvas 宽度 * 缩放 8 canvas.height = height * scale; //定义canvas高度 *缩放 9 canvas.style.width = shareContent.clientWidth * scale + "px"; 10 canvas.style.height = shareContent.clientHeight * scale + "px"; 11 canvas.getContext("2d").scale(scale, scale); //获取context,设置scale 12 let opts = { 13 scale: scale, // 添加的scale 参数 14 canvas: canvas, //自定义 canvas 15 logging: false, //日志开关,便于查看html2canvas的内部执行流程 16 width: width, //dom 原始宽度 17 height: height, 18 useCORS: true // 【重要】开启跨域配置 19 }; 20 html2canvas(shareContent,opts).then()
the operation is insecure
canvas.toDataURL 报错 the operation is insecure
canvas.toDataURL(type, encoderOptions);语法
配置如:canvas.toDataURL("image/png", 0.7);
参数type指定图片类型,如果指定的类型不被支持则以默认值image/png替代;
encoderOptions(第二个参数)可以为image/jpeg或image/webp类型的图片设置图片质量,取值0-1,超出则以默认值0.92替代。
html2canvas在微信中base64码为空
在微信中或者可以说在移动端浏览器里,canvas.toDataURL不成功。canvas.toDataURL(type) 得到空的 data:;
引发这个问题的操作可能有2中,1、canvas被污染,2、生成图片过大,base64码有长度限制
不可见的元素截图后是空白
没法截图看不见的,比如opacity为0的东西,或者visibility为hidden的,更别说display:none了。
解决方法是让canvas部分隐藏到后边。最终选择方案,层级设为-1,上一层的把他盖住。前提是上一层要又一个可以设置的背景色,能把他盖住不被世人看到
html2canvas结合微信里的长按存图功能
先用html2canvas拿到一个html转为canvas的base64码,
再在页面建立一个img元素,src=base64码,插入dom中,盖在所有元素的最上方(或者需要用户长按保存的地方),opacity设置为0。
然后用户就长按保存,存下来的就是事先准备好的覆盖在那里的那个不可见得透明图。
事实证明,图片透明不可见覆盖在页面上边,微信里是可以存图的。
html2canvas 截图跨域
图片跨域时报错现象
这个时候你要去看图片的header头有没有这个:
看图片本身是否允许跨域访问:
上边这个是一个允许的图片。下边这个不允许,就截取不到。
主要是用于解决了本次问题的地方:useCORS:true 这个参数很重要,没有配置的话,依旧是不能解决问题的;
根据现有的解决方案大致有两种:
(1).在跨域的服务器上设置header设置为允许跨域请求。 在服务器上设置header设置允许跨域请求
(2).借助代理脚本获得外域图片的 base64 编码后的字符串,本文未采用。
作者:旧旧的 <393210556@qq.com> 解决问题的方式,就是解决它一次