3

This is a repeat of this question: Get image width and height from the Base64 code in JavaScript but I am asking with regards to deno. Deno does not have the new Image() that is used in all the solutions I have read. I intend on doing this in an edge function so reduced dependencies is important. A few things I have considered:

Is there a way to do this without a package or to do it simply using some built-in package?

2
  • Maybe you can check this and this. Commented Nov 5, 2023 at 5:25
  • is deno capable to creating an element? I'm not sure how it works exactly. But the new Image() is not available so that solution wouldn't work here Commented Nov 5, 2023 at 6:23

1 Answer 1

3

In order to get image width & height without external libraries, you need to parse the image header. If you're only dealing with few image type you could easly avoid using third-party libs.

For example for parsing a png image width & height from a base64 encoded image you could do it like this:

import { decode } from "https://deno.land/std/encoding/base64.ts"

const pngImageb64 = /* some png image in base64 */

const pngImage = decode(pngImageb64);
const dataView = new DataView(pngImage.buffer);
// The width and height are 4-byte integers starting 
// at byte offset 16 and 20, respectively.
const width = dataView.getUint32(16);
const height = dataView.getUint32(20);

Ref: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html

Width and height give the image dimensions in pixels. They are 4-byte integers. Zero is an invalid value. The maximum for each is 2^31


For jpeg it's a bit harder since the dimensions are stored in the Start of Frame (SOF) markers. The following should work for most cases (only tested it in a few jpegs)

const jpegImageb64 = /* some jpeg image in base64 */

const jpegImage = decode(jpegImageb64);
const dataView = new DataView(jpegImage.buffer);

let width, height;
for (let i = 0; i < dataView.byteLength - 9; i++) {  // - 9 prevent out-of-bounds access
    if (dataView.getUint16(i) === 0xFFC0 || dataView.getUint16(i) === 0xFFC2) {
      height = dataView.getUint16(i + 5);
      width = dataView.getUint16(i + 7);
      break;
  }
}

Other possible solutions:


To detect the image type so you know which parser to use, you have to read the first bytes of the image, you could use file-type lib for it (after decoding base64)

See https://github.com/sindresorhus/file-type/blob/5c42f8057f056fe41cbe4bffb53f56987d02e909/core.js#L238-L249 for detecting jpeg yourself.


Depending on the image type you're dealing with, it could be more complicated, if you support a wide variety of image formats I would recommend using a library such as sharp for parsing that data.

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.