Open ONE-SUNDAY opened 7 years ago
在微信中使用 <input type="file" multiple accept="image/*"> 传入照片后,绘制到 Canvas 中时会发现绘制的图像方向不对(手 Q 端貌似不会存在这个问题),这时需要使用 exif.js 来解决。
<input type="file" multiple accept="image/*">
Exif.js 提供了 JavaScript 读取图像的原始数据的功能扩展,例如:拍照方向、相机设备型号、拍摄时间、ISO 感光度、GPS 地理位置等数据。
<input class="uploadBtn" type="file" multiple accept="image/*">
document.querySelector(".uploadBtn").addEventListener("change", previewImgFile, false); function previewImgFile() { var _files = files || event.target.files; var _index = index || 0; var reader = new FileReader(); reader.onload = function(event) { var image = new Image(); image.src = event.target.result; var orientation; image.onload = function() { EXIF.getData(image, function() { // 获取图像的数据 EXIF.getAllTags(this); // 获取图像的全部数据,值以对象的方式返回 orientation = EXIF.getTag(this, "Orientation"); // 获取图像的拍摄方向 var rotateCanvas = document.createElement("canvas"), rotateCtx = rotateCanvas.getContext("2d"); // 针对图像方向进行处理 switch (orientation) { case 1 : rotateCanvas.width = image.width; rotateCanvas.height = image.height; rotateCtx.drawImage(image, 0, 0, image.width, image.height); break; case 6 : // 顺时针 90 度 rotateCanvas.width = image.height; rotateCanvas.height = image.width; rotateCtx.translate(0, 0); rotateCtx.rotate(90 * Math.PI / 180); rotateCtx.drawImage(image, 0, -image.height, image.width, image.height); break; case 8 : rotateCanvas.width = image.height; rotateCanvas.height = image.width; rotateCtx.translate(0, 0); rotateCtx.rotate(-90 * Math.PI / 180); rotateCtx.drawImage(image, -image.width, 0, image.width, image.height); break; case 3 : // 180 度 rotateCanvas.width = image.width; rotateCanvas.height = image.height; rotateCtx.translate(0, 0); rotateCtx.rotate(Math.PI); rotateCtx.drawImage(image, -image.width, -image.height, image.width, image.height); break; default : rotateCanvas.width = image.width; rotateCanvas.height = image.height; rotateCtx.drawImage(image, 0, 0, image.width, image.height); } var rotateBase64 = rotateCanvas.toDataURL("image/jpeg", 0.5); }); } } reader.readAsDataURL(_files[_index]); }
1、图片模糊
默认生成的 Canvas 是 1 倍图,在移动端 Retina 屏幕下显示模糊,可以通过 2 倍图的方式解决:
var stageWidth = $(".stage").width(), stageHeight = $(".stage").height(); var retinaCanvas = document.createElement("canvas"); retinaCanvas.width = stageWidth * 2; retinaCanvas.height = stageHeight * 2; retinaCanvas.style.width = stageWidth + "px"; retinaCanvas.style.height = stageHeight + "px"; var ctx = retinaCanvas.getContext("2d"); ctx.scale(2, 2); html2canvas(document.querySelector(".stage"), { canvas: retinaCanvas, onrendered: function(canvas) { var base64 = canvas.toDataURL(); // 返回 base64 } });
2、图片偏移
html2canvas 是解析 DOM 元素实际的样式来生成图片,如果对元素位置进行调整,例如设置了 top、left 或者 margin-top、margin-left 的样式会导致生成的图片偏移。
top
left
margin-top
margin-left
ctx.transform(-x, -y); // 计算一下偏移的值,通过 transform 方法来修正回去
3、ICON 模糊
即使是使用了 2 倍图,生成后的图片里的 ICON 还是模糊,可以用 SVG 的方式去代替图片 ICON。
4、不支持设置 border-radius 的元素
如果你需要在一个头像中设置 border-radius: 50% 在转为图片后,你会发现并不成功,解决方法在源码 html2canvas.js 中加入以下代码:
border-radius: 50%
html2canvas.js
tlh = borderRadius[0][0], tlv = borderRadius[0][1], trh = borderRadius[1][0], trv = borderRadius[1][1], brh = borderRadius[2][0], brv = borderRadius[2][1], blh = borderRadius[3][0], blv = borderRadius[3][1]; /* S 插入这段代码 */ var halfHeight = Math.floor(height / 2); tlh = tlh > halfHeight ? halfHeight : tlh; tlv = tlv > halfHeight ? halfHeight : tlv; trh = trh > halfHeight ? halfHeight : trh; trv = trv > halfHeight ? halfHeight : trv; brh = brh > halfHeight ? halfHeight : brh; brv = brv > halfHeight ? halfHeight : brv; blh = blh > halfHeight ? halfHeight : blh; blv = blv > halfHeight ? halfHeight : blv; /* E 插入这段代码 */ var topWidth = width - trh, rightHeight = height - brv, bottomWidth = width - brh, leftHeight = height - blv;
图片偏移的应该是 ctx.translate(-x, -y);
优秀
👍,碰到类似问题参考博主解决了
使用到的库
将拍摄的图像绘制到 Canvas 后,图像方向不对
在微信中使用
<input type="file" multiple accept="image/*">
传入照片后,绘制到 Canvas 中时会发现绘制的图像方向不对(手 Q 端貌似不会存在这个问题),这时需要使用 exif.js 来解决。html2canvas 使用过程中遇到的问题
1、图片模糊
默认生成的 Canvas 是 1 倍图,在移动端 Retina 屏幕下显示模糊,可以通过 2 倍图的方式解决:
2、图片偏移
html2canvas 是解析 DOM 元素实际的样式来生成图片,如果对元素位置进行调整,例如设置了
top
、left
或者margin-top
、margin-left
的样式会导致生成的图片偏移。3、ICON 模糊
即使是使用了 2 倍图,生成后的图片里的 ICON 还是模糊,可以用 SVG 的方式去代替图片 ICON。
4、不支持设置 border-radius 的元素
如果你需要在一个头像中设置
border-radius: 50%
在转为图片后,你会发现并不成功,解决方法在源码html2canvas.js
中加入以下代码: