我试图通过仅使用图像 URL、宽度和高度向其发布消息来在 Worker 内创建 ImageData。为了使它工作,我需要获取图像并获取 ArrayBuffer。有了它,我应该能够创建新的 ImageData:
//worker.ts
fetch(e.data.url)
.then( r => r.arrayBuffer() )
.then( buffer => {
console.log(buffer.byteLength); // 4022
new ImageData((new Uint8ClampedArray(buffer)), e.data.width, e.data.height);
});
我收到以下错误:输入数据字节长度不是(4 * 宽度)的倍数。
对于 Chrome,我不仅可以将 URL 发布到 Worker,还可以将之前在主线程中使用画布创建的整个 ArrayBuffer 发布,并且可以正常工作:
//main thread
const canvas = typeof OffscreenCanvas !== 'undefined' ?
new OffscreenCanvas(img.width, img.height) :
document.createElement('canvas'),
ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
const imageData: ImageData = ctx.getImageData(0, 0, img.width, img.height);
console.log(imageData.data.buffer.byteLength); // 106288
问题在于 Firefox worker.postMessage() 只能处理较小的消息,例如 URL,而不是整个 ArrayBuffer(需要很长时间来序列化和反序列化大消息)。这就是为什么我尝试只发送 URL、高度、宽度并在 Worker 本身中获取图像的方法。问题在于 Worker 中获取的 ArrayBuffer - 它比在主线程中使用画布创建的要小得多(相同的 URL,不同的方法,不同的 ArrayBuffer)。如果我在 Worker 中有相同的 ArrayBuffer,则会创建 ImageData(不会引发错误)。
我的问题是我做错了什么,如何在使用 fetch/axios 等获取图像后创建 ImageData。