在我的9到5时,我们定期使用Base64图像处理图像上传表单/应用程序等,以便它简单地使用#64;通过AJAX传输和其他一些次要原因。
但是,在使用此方法时,我们经常遇到问题。 Android设备。
浏览器有时会挂起 - 显示可用的内存错误 消息,然后重新启动。其他时候它只是重新开始没有 弹出任何警报。
仅在大型图片和旧Android设备上发生这种情况 有很多应用程序在运行等等。
一种解决方案是在DataUrl整个过程之前减小图像的大小 - 但有时这还不够 - 我们需要图像具有相对大小,例如我们不能使用图像的针头大小。
我们如何阻止浏览器暂停?
我想到了一个解决方案,我会使用WebWorkers在后台对其进行异步编码 - 但我在想这会产生什么不同? UI可能不会冻结,但无论如何都会使用内存。
还有其他可能的解决方案吗?
注意 :我们仅定位到Android 4.1+和iOS6 +
反正
这是我们目前用于调整和编码Base64的功能。
function resizeCanvasImage(img, maxWidth, maxHeight) {
var imgWidth = img.width,
imgHeight = img.height;
var ratio = 1, ratio1 = 1, ratio2 = 1;
ratio1 = maxWidth / imgWidth;
ratio2 = maxHeight / imgHeight;
// Use the smallest ratio that the image best fit into the maxWidth x maxHeight box.
if (ratio1 < ratio2) {
ratio = ratio1;
}
else {
ratio = ratio2;
}
var canvas = document.createElement("canvas");
var canvasContext = canvas.getContext("2d");
var canvasCopy = document.createElement("canvas");
var copyContext = canvasCopy.getContext("2d");
var canvasCopy2 = document.createElement("canvas");
var copyContext2 = canvasCopy2.getContext("2d");
canvasCopy.width = imgWidth;
canvasCopy.height = imgHeight;
copyContext.drawImage(img, 0, 0);
// init
canvasCopy2.width = imgWidth;
canvasCopy2.height = imgHeight;
copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);
var rounds = 2;
var roundRatio = ratio * rounds;
for (var i = 1; i <= rounds; i++) {
// tmp
canvasCopy.width = imgWidth * roundRatio / i;
canvasCopy.height = imgHeight * roundRatio / i;
copyContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvasCopy.width, canvasCopy.height);
// copy back
canvasCopy2.width = imgWidth * roundRatio / i;
canvasCopy2.height = imgHeight * roundRatio / i;
copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);
} // end for
// return Base64 string of the downscaled image
canvas.width = imgWidth * roundRatio / rounds;
canvas.height = imgHeight * roundRatio / rounds;
canvasContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvas.width, canvas.height);
var dataURL = canvas.toDataURL();
return dataURL;
}