I have this
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOcAAABnCAYAAAD7RFX4AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFP
And here is a new updated es6 version 3 years later with a tiny bit of help from typed arrays that is synchronous and where you don't have to load the hole image to memory to figure it out. So its faster :)
also don't require any DOM so it can work inside Workers
function getPngDimensions(base64) {
const header = atob(base64.slice(0, 50)).slice(16,24)
const uint8 = Uint8Array.from(header, c => c.charCodeAt(0))
const dataView = new DataView(uint8.buffer)
return {
width: dataView.getInt32(0),
height: dataView.getInt32(4)
}
}
// Just to get some base64 png example
const canvas = document.createElement('canvas')
const base64 = canvas.toDataURL().split(',')[1]
const dimensions = getPngDimensions(base64)
console.log(dimensions)
edit: my recommendation is also that you should try to use typed arrays instead of base64 and blobs instead of typed arrays when possible, base64 is the worse container and use more memory.
So here is a solution for you who already have a blob:
document.createElement('canvas').toBlob(async blob => {
// blob.arrayBuffer() is the new way to read stuff
// may not work in all browser
let dv = new DataView(await blob.slice(16, 24).arrayBuffer())
console.log({
width: dv.getInt32(0),
height: dv.getInt32(4)
})
})
// you could also try out the new experimental createImageBitmap
// don't use image or canvas but this also works in web workers
// and it also works for more than just png's
// could expect this is more havier/slower than just reading bytes 16-24
document.createElement('canvas').toBlob(async blob => {
const bitmap = await createImageBitmap(blob)
const { width, height } = bitmap
bitmap.close() // GC
console.log({ width, height })
})