context.getImageData().data returning 0 for pixels past a certain point

I am using getImageData() to retrieve the pixel data of .jpg images. The function works perfectly for small images but doesn’t on larger images (say around 240×240 and up). With larger images it ends up just returning 0 for all pixels beyond a certain point.

The image gets drawn perfectly and my use cases fall within the limits mentioned elsewhere with widths and heights in the tens of thousands being allowed.

function showImage(fileReader) {
    var img = document.getElementById("myImage");  
    img.onload = () => getImageData(img);
    img.src = fileReader.result; 
}

function getImageData(img) {
    ctx.drawImage(img, 0, 0);
    let imageArr = ctx.getImageData(0, 0, img.width, img.height).data;
    imageHeight = img.height;
    imageWidth = img.width;

    console.log(imageArr);

I can’t seem to find any other posts with this exact issue. I get no console errors.

Is there something wrong with what I am doing and how can I get past this ?

Answer

You probably just forgot to set the canvas width/height to the same size as the image before drawing the image to the canvas…

ctx.canvas.width = img.width
ctx.canvas.height = img.height
ctx.getImageData(...

Anyway here is a modern approach that uses OffscreenCanvas + createImageBitmap
(this makes it possible to run it in web workers)

/**
 * @param {ImageBitmap} bitmap
 */
function getClampedArr (bitmap) {
  // Set the canvas to be the same size as the image
  const ctx = new OffscreenCanvas(bitmap.width, bitmap.height).getContext('2d')
  ctx.drawImage(bitmap, 0, 0)
  return ctx.getImageData(0, 0, bitmap.width, bitmap.height).data
}

// Simulate a file u would normaly get from a file input
const url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
fetch(url).then(r => r.blob()).then(file => 
    
  // This is what you want to do with your file
  createImageBitmap(file)
    .then(getClampedArr)
  
).then(console.log, console.error)