Solution 1 :

you could construct a ImageData manually but for that you need a Uint8ClampedArray. For that you would also have to decode a binary file to pixel data yourself. So you probably want to use canvas or offscreanCanvas for that anyway

but there are some tools to ease the way to get imageData from blob using createImageBitmap
This imageBitmap contains the pixel data but you are not able to read it, but at least it will be faster to paint it to a canvas element.

(async () => {
// just to simulate a file you would get from file input
const res = await fetch('https://httpbin.org/image/png')
const blob = await res.blob()
const file = new File([blob], 'image.png', blob)

async function getImageData (blob) {
  const bitmap = await createImageBitmap(blob)
  const canvas = document.createElement('canvas')
  const ctx = canvas.getContext('2d')

  canvas.width = bitmap.width
  canvas.height = bitmap.height

  ctx.drawImage(bitmap, 0, 0)
  return ctx.getImageData(0, 0, canvas.width, canvas.height)
}

getImageData(blob).then(imageData => console.log(imageData.width))

})()

but you might not use createImageBitmap due to compatibility issues, so then i suggest that you instead of creating a image from file input -> base64 -> image with the FileReader that you instead go from file to image using a pointer references with object urls

const img = new Image()
img.src = URL.createObjectURL(file)

this will use less resources cuz you don’t need to encode it to base64 and decode it back to binary again, it will use less memory since it will just load the image from your disk instead directly

Problem :

I want to access and manipulate an image’s binary data using javascript. As far as I could research, it can be done using Canvas API – creating a canvas and a context in memory, and then using their built-in methods. What I’ve come up looks like this:

function fileToBase64(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(<string>reader.result);
    reader.onerror = () => reject(reader.error);
    reader.readAsDataURL(file);
  });
}

function base64ToImageData(base64: string): Promise<ImageData> {
  return new Promise((resolve, reject) => {
    const img = new Image();
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    img.onload = () => {
      canvas.width = img.width;
      canvas.height = img.height;
      ctx.drawImage(img, 0, 0);
      const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
      resolve(imageData);
    }
    img.onerror = () => reject();
    img.src = base64;
  });
}

And what I don’t like about this approach is that it is verbose and probably uses more resources than it should.
So the question is: Is there a way to get a binary representation of an image without using canvas API?

Comments

Comment posted by Endless

Is there a way to get a binary representation?

By