我一直在 React 中开发一个具有裁剪功能的应用程序。该代码应将图像转换为画布,然后将画布转换为Blob,以便我稍后可以在代码中使用该 base64 字符串。一切都很好,并且在我的 Android 手机、电脑和不同浏览器上都能正常工作。唯一的问题是 iPhone。仅当从 iPhone 上传并选择实际大小时,我才会从 canvas.toBlob() 获取 null 值。当我上传图像并选择大而不是实际大小时,代码运行正常。这是代码:
const getCroppedImg = (image: any, crop: Crop) => {
const canvas = document.createElement('canvas');
const pixelRatio = window.devicePixelRatio;
const scaleX = image.naturalWidth / image.width;
const scaleY = image.naturalHeight / image.height;
const ctx = canvas.getContext('2d');
canvas.width = crop.width * pixelRatio * scaleX;
canvas.height = crop.height * pixelRatio * scaleY;
if(ctx == null){
return;
}
ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
ctx.imageSmoothingQuality = 'high';
ctx.drawImage(
image,
crop.x * scaleX,
crop.y * scaleY,
crop.width * scaleX,
crop.height * scaleY,
0,
0,
crop.width * scaleX,
crop.height * scaleY
);
return new Promise((resolve, reject) => {
canvas.toBlob(
(blob) => {
if (!blob) {
reject(new Error('Canvas is empty'));
console.error('Canvas is empty');
alert("Canvas is emtpy")
return;
}
const reader = new FileReader();
reader.readAsDataURL(blob)
reader.onloadend = function(){
if(reader.result != null && typeof(reader.result) === 'string'){
const base64data:string = reader.result
resolve(base64data);
}
}
},
'image/jpeg',
0.5
);
});
}
图像大小并不重要,我从计算机上传了更大的文件大小,它可以工作,而且我还制作了 6000 x 6000 像素的图像,从我的计算机上传也很好。我真的很困惑,不知道从哪里开始。我见过有人抱怨 Safari 上的 toBlob,但如果未选择实际大小,toBlob 工作正常。另外,iPhone 上的 chrome 也会发生同样的情况。
任何线索都会有帮助,因为我没有想法了。我认为发布其他代码只会使这篇文章变得臃肿,但如果有人需要知道应用程序中还发生了什么,我也很乐意发布。
这里是 toBlob() 的浏览器限制的链接。
Safari 自 2017 年和 iOS 11 起就被列为支持,但仍然不支持“质量”。看来您正在以某种形式使用该参数“imageSmoothingQuality = 'high'”。
如果最终遇到浏览器支持问题,一种解决方案是使用 blueimp-canvas-to-blob 之类的东西来填充它。或者显然只是不使用有问题的参数。