I'm trying to create ImageData inside the Worker by only posting the message to it with the image URL, width, and height. To make it work I need to fetch the image and get ArrayBuffer. With that I should be able to create new 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);
});
I'm getting the following error: The input data byte length is not a multiple of (4 * width).
For Chrome I'm able to post to the Worker not just URL, but the whole ArrayBuffer created before in the main thread with canvas and that works:
//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
The problem is that with Firefox worker.postMessage() can only handle smaller messages, like URL, not whole ArrayBuffer (takes a very long time to serialize and deserialize large messages). That's why I'm trying the approach with sending only URL, height, width, and getting the image in Worker itself. The problem is with ArrayBuffer fetched in the Worker - it's much smaller than the one created using canvas in the main thread (the same URL, different methods, different ArrayBuffer). If I would have the same ArrayBuffer in the Worker, ImageData would be created (not throwing error).
My question is what I'm getting wrong, how can I create ImageData after fetching image using fetch/axios, etc.