首先 本人是一个canvas小白 基本不懂canvas的原理,拿到同事写的代码直接copy过来也没看文档(项目催的紧且文档是英文的) 话不多说 上代码 只是说出我的解决思路很多为什么还要花时间研究 比如canvas我都不会
复制代码
html2canvas(document.querySelector(".upload_box")).then((canvas) => {
var imgData = canvas.toDataURL('image/png');
$('#save_img').html($(''" alt="">'));
})
复制代码
如此简单是不是!获取dom 把返回的canvas转成图片显示! 遇到两个问题:
- 部分图片没有生成
- 生成的图片特别模糊(文字和图片都是模糊的)手机上更糊
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($(''" alt="">'));
})
复制代码
酱紫 远程的图片页也可以了 不会出现空白页!真是开心,比转成程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给我了! 完全搞定了!撒花
写下这个记录帖 虽然问题暂时解决了 但是还有更多的不懂在等着我去看