Read the dimensions of a PNG image
Back to snippetsThe following code can be used to read the width and height of a PNG image (in Buffer
form) in TypeScript.
// The first eight bytes of a PNG file always contain the following (decimal) values://// 137, 80, 78, 71, 13, 10, 26, 10//// Source: http://www.libpng.org/pub/png/spec/1.2/PNG-Structure.htmlconst pngSignature = new Buffer([137, 80, 78, 71, 13, 10, 26, 10]).toString("ascii");const ihdrChunkHeader = "IHDR";// See https://web.archive.org/web/20190208215723/http://www.jongware.com/pngdefry.htmlconst cgbiChunkHeader = "CgBI";const cgbiChunkLen = 16;const Result = {NOT_PNG: 0,CONTAINS_CGBI_CHUNK: 1,PNG: null,};function parsePng(buffer: Buffer) {// Bytes 1-8 must contain the PNG signatureif (buffer.toString("ascii", 0, 8) !== pngSignature) return Result.NOT_PNG;// After the signature, PNG files contain N chunks. The first 4 bytes of// each chunk contain the chunk length.const firstChunkHeader = buffer.toString("ascii", 12, 16);if (firstChunkHeader === cgbiChunkHeader) {// If Apple's CgBI chunk is present, then the IHDR chunk must be the second// chunk.const secondChunkHeader = buffer.toString("ascii",12 + cgbiChunkLen,16 + cgbiChunkLen);if (secondChunkHeader !== ihdrChunkHeader) return Result.NOT_PNG;return Result.CONTAINS_CGBI_CHUNK;}if (firstChunkHeader !== ihdrChunkHeader) return Result.NOT_PNG;return Result.PNG;}export function pngDimensions(buffer: Buffer) {const result = parsePng(buffer);if (result === Result.NOT_PNG) throw new Error("Buffer is not a PNG file");// If the CgBI chunk is present, then the IHDR chunk comes 16 bytes laterconst offset = result === Result.CONTAINS_CGBI_CHUNK ? cgbiChunkLen : 0;return {// The first 8 bytes of the IHDR chunk are the width and height of// the image (4 bytes for each).width: buffer.readUInt32BE(16 + offset),height: buffer.readUInt32BE(20 + offset),};}