记录html2canvas使用过程中遇到的图片跨域、模糊失真、base64、偏移等问题
html2canvas
能把dom直接生成canvas,用法也很简单:
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas)
});
但是在使用的过程中会遇到许多的问题,在此记录使用过程中遇到的问题
涉及到的跨域问题, canvas
的画布中对于图片的域也是有要求的,那我们应该怎么解决呢?
可以尝试的解决方案如下:
allowTaint:true
或 useCORS:true
(二者不可共同使用, 设置useCORS:true
,allowTaint: true
, 跨域的图片绘制,canvas被污染,就无法用canvas.toDataUrl()
转化为图片了)crossOrigin='anonymous'
Access-Control-Allow-Origin
或使用代理其中第三步是最重要的,不设置则前两步设置了也无效。
服务器需要配置Access-Control-Allow-Origin信息, *
通配符表示允许任
``
为了解决跨域的问题,经常需要使用到base64
格式的图片
原理:使用xhr请求图片,并设置返回的文件类型为Blob对象[xhr.responseType = “blob”]
使用FileReader 对象接收blob
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>js 图片转base64方式</title>
</head>
<body>
<p id="container1"></p>
<script>
getBase64("https://z649319834.github.io/Learn_Example/video_track/webvtt.jpg")
function getBase64(imgUrl) {
window.URL = window.URL || window.webkitURL;
var xhr = new XMLHttpRequest();
xhr.open("get", imgUrl, true);
// 至关重要
xhr.responseType = "blob";
xhr.onload = function () {
if (this.status == 200) {
//得到一个blob对象
var blob = this.response;
console.log("blob", blob)
// 至关重要
let oFileReader = new FileReader();
oFileReader.onloadend = function (e) {
let base64 = e.target.result;
console.log("方式一》》》》》》》》》", base64)
};
oFileReader.readAsDataURL(blob);
//====为了在页面显示图片,可以删除====
var img = document.createElement("img");
img.onload = function (e) {
window.URL.revokeObjectURL(img.src); // 清除释放
};
let src = window.URL.createObjectURL(blob);
img.src = src
document.getElementById("container1").appendChild(img);
//====为了在页面显示图片,可以删除====
}
}
xhr.send();
}
</script>
</body>
</html>
实现原理:使用canvas.toDataURL()
方法, 需要解决图片跨域问题 image.crossOrigin ='anonymous'
function() {
let canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
const img = new Image()
img.crossOrign = 'Anonymous'
img.onload = function() {
canvas.height = img.height
canvas.width = img.width
ctx.drawImage(img, 0, 0)
let dataUrl = canvas.toDataUrl('image/png')
}
}
https://www.cnblogs.com/lxk0301/p/11569044.html
关于图片模糊失真的问题,可以使用html2canvas
中的scale
属性,当然,并不是设置越大越好,虽然图片质量高,但是性能消耗也大。
let scale = window.devicePixelRatio // 获取设备像素比
html2canvas(window.document.querySelector('.content'), {
useCORS: true,
scale: scale,
width: imgWidth,
height: imgHeight
}).then((canvas) => {
// canvas
})
获取设备像素比的方法
function getPixelRatio(context) {
let backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
}
解决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);