npm.io
0.3.1 • Published 1 week ago

image-meta

Licence
MIT
Version
0.3.1
Deps
0
Size
42 kB
Vulns
0
Weekly
0
Stars
138

image-meta

npm version npm downloads Codecov bundle

Detect image type and size using pure JavaScript. It has no dependencies and works in Node.js, browsers and other runtimes.

Usage

import { imageMeta } from "image-meta";

const res = await fetch(url);
const data = new Uint8Array(await res.arrayBuffer());

const meta = imageMeta(data);
// => { type: "png", width: 123, height: 456 }

In Node.js, a Buffer works as input because it is a Uint8Array:

import { readFile } from "node:fs/promises";
import { imageMeta } from "image-meta";

const meta = imageMeta(await readFile("./image.jpg"));

The type is detected from the file contents, not the file extension.

Result

type ImageMeta = {
  type?: string; // detected format, e.g. "png"
  width: number; // of the largest image when there are several
  height: number;
  orientation?: number; // EXIF orientation (jpg)
  images?: Omit<ImageMeta, "images">[]; // all embedded images (ico, cur, icns)
  animated?: boolean; // animation or image sequence (gif, png, webp, avif, heic, jxl)
  pages?: number; // number of frames or pages (gif, png, webp, tiff)
};
Animation and pages

animated and pages are read from the headers without decoding the image, and are left undefined when they can't be found cheaply (for example in a truncated file). A single frame is not reported as animated. For tiff, every directory counts as a page, including thumbnails and reduced-resolution images (e.g. in camera raw files).

Format animated pages
gif more than one frame number of frames
png (APNG) acTL chunk before IDAT acTL frame count
webp VP8X animation flag number of ANMF chunks
avif / heic sequence brand (avis, msf1, …) and a moov box -
jxl have_animation in the image metadata -
tiff - length of the IFD chain

These values are best-effort hints, useful for UX and processing decisions (keeping an animation when converting, skipping a step for single-frame images, showing a frame count). They are not reliable for security decisions such as size or resource limits: image-meta parses headers on its own, so for malformed or crafted files its answer can differ from what a decoder will do. Ask the decoder that will process the file when you need a guarantee.

Error handling

imageMeta throws an error if the input is not a Uint8Array, the format is unsupported, or the data is invalid. Wrap calls that take untrusted input in try/catch:

try {
  const meta = imageMeta(data);
} catch {
  // Not a supported image
}

Supported formats

avif, bmp, cur, dds, gif, heic, icns, ico, j2c, jp2, jpg, jxl, ktx, png, pnm, psd, svg, tga, tiff, webp

Development

  • Clone this repository
  • Install the latest LTS version of Node.js
  • Enable Corepack using corepack enable
  • Install dependencies using pnpm install
  • Run interactive tests using pnpm dev

See AGENTS.md for the project layout and how to add a new format.

License

Made with

Based on image-size by Aditya Yadav and contributors.

Published under MIT License.