我有来自其他服务器的img
<img src="https://cloudserver/1.jpg">
在单击此img时,我想转换为File对象,以向服务器发送发布请求。在执行此功能后,我看到所有字节的数据都为0,不了解发生了什么重叠?在搜索中,我发现有关需要等待的问题,然后图像已完成加载,但是我100%已加载图像。
imgToFile: function (imageElement){
imageElement.crossOrigin="anonymous";
var canvasElement = document.createElement("canvas");
canvasElement.width = imageElement.width;
canvasElement.height = imageElement.height;
var canvasContext = canvasElement.getContext("2d");
canvasContext.drawImage(imageElement, 0, 0);
var imageData = canvasContext.getImageData(0, 0, imageElement.width, imageElement.height).data;
var buffer = new Uint8Array(imageData.length);
for(var index = 0; index < imageData.length; index++)
buffer[index] = imageData[index];
var imageBlob = new Blob(buffer);
return new File([imageBlob], /\/([^/]+)$/.exec(imageElement.src)[1]);
}
对于我以为我知道这部分规格的人感到非常惊讶,但是事实证明,更改since 2016属性状态是crossorigin
属性状态的一部分。img的relevant mutations,将强制输入refetching of the image source。
Chrome仅赶上规格relatively recently(M84),Firefox仍然没有,因此会抱怨图像确实弄脏了画布,并抛出错误消息。
另一方面,Chrome会在您更改crossOrigin
IDL属性后立即重新获取图像,这次使用正确的CORS标头。因此,当您在该浏览器中点击drawImage
时,它仍不会获取符合CORS的资源(即使它是同一文件,因为它带有不同的标头,浏览器也会再次完全获取它)。
与您的想法相反,您的图像仍未加载到Chrome中。
[要解决此问题,您可以在js脚本中添加onload
事件处理程序,但是您还需要通过再次设置src
属性(甚至将其设置为相同的值)来强制为其他浏览器重新刷新图像):
onload = (evt) => {
const img = document.querySelector( 'img' );
img.onload = (evt) => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.drawImage(img,0,0);
console.log(...ctx.getImageData(250,120,1,1).data);
};
img.crossOrigin = 'anonymous';
img.src = img.src; // force refetching for non-Chrome browsers
};
img { width: 300px }
<img src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png">
但是最好的方法是从一开始就直接使用适当的CORS标头直接请求您的图像,因此,您不会让用户下载相同文件的两倍而不花钱。
onload = (evt) => {
const img = document.querySelector( 'img' );
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.drawImage(img,0,0);
console.log(...ctx.getImageData(250,120,1,1).data);
};
img { width: 300px }
<img src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png" crossorigin="anonymous">