1

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?

1
  • Is there a way to get a binary representation? think you mean ImageData that represents all rgba pixel data that you later can manipulate? there are many image binary representation, png, jpg, webp, etc Commented Jun 16, 2020 at 12:29

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.