Reading Image Metadata: Dimensions, Format, and Hidden Data
Every digital image carries more than pixel data. Embedded metadata includes dimensions, color profile, camera settings, GPS coordinates, and even editing history. Understanding this hidden data matters for privacy, performance, and debugging.
What Metadata Lives Inside an Image?
Image files contain several categories of embedded information:
Technical metadata includes width, height, color depth, color space, and format-specific encoding parameters. This is essential for rendering the image correctly.
EXIF data (Exchangeable Image File Format) is embedded by cameras and phones. It records:
- Camera make and model
- Exposure settings (shutter speed, aperture, ISO)
- Date and time the photo was taken
- GPS coordinates (latitude and longitude)
- Orientation (rotation)
- Thumbnail preview
IPTC data stores editorial information: captions, keywords, copyright notices, and credits. Photographers and agencies use this for cataloging.
XMP data (Extensible Metadata Platform) is Adobe's metadata framework. It can duplicate EXIF and IPTC fields and adds editing history, software used, and custom properties.
Reading Metadata in JavaScript
The browser does not expose EXIF data through standard APIs. You need to parse the binary file structure. Here is how to read basic properties:
// Read basic dimensions using the Image API
function getImageDimensions(file: File): Promise<{
width: number;
height: number;
type: string;
size: number;
}> {
return new Promise((resolve) => {
const img = new Image();
const url = URL.createObjectURL(file);
img.onload = () => {
resolve({
width: img.naturalWidth,
height: img.naturalHeight,
type: file.type,
size: file.size,
});
URL.revokeObjectURL(url);
};
img.src = url;
});
}
For full EXIF extraction, parse the JPEG binary structure. EXIF data starts at the APP1 marker (0xFFE1) in the file header:
async function readExifOrientation(file: File): Promise<number> {
const buffer = await file.slice(0, 65536).arrayBuffer();
const view = new DataView(buffer);
// Verify JPEG SOI marker
if (view.getUint16(0) !== 0xffd8) return 1;
let offset = 2;
while (offset < view.byteLength) {
const marker = view.getUint16(offset);
if (marker === 0xffe1) {
// Found APP1 (EXIF) segment
const exifOffset = offset + 10; // Skip marker, length, "Exif\0\0"
// Parse IFD0 for orientation tag (0x0112)
// ... (full parser omitted for brevity)
break;
}
offset += 2 + view.getUint16(offset + 2);
}
return 1; // Default orientation
}
Libraries like exifr handle the full complexity of EXIF parsing, including GPS data, thumbnails, and maker notes.
The Privacy Problem
GPS coordinates in EXIF data are a serious privacy concern. A photo taken at home and shared publicly reveals your home address to anyone who reads the metadata. Social media platforms strip EXIF data on upload, but many other contexts do not:
- Images uploaded to forums, documentation sites, or wikis
- Images shared via email or messaging apps
- Images in CMS platforms and blogs
- Images in GitHub repositories
Always strip metadata before publishing images. In a build pipeline:
# Using exiftool to strip all metadata
exiftool -all= -overwrite_original image.jpg
# Using sharp in Node.js
sharp("input.jpg")
.withMetadata(false) // Strip EXIF, IPTC, XMP
.toFile("output.jpg");
EXIF Orientation and Display Bugs
Cameras store photos in a fixed orientation and record the actual orientation as an EXIF tag (values 1-8 representing rotations and flips). Modern browsers respect this tag, but older software and some image processing libraries do not.
This leads to a common bug: an image appears rotated 90 degrees after processing because the library stripped the orientation tag without physically rotating the pixels.
The fix is to apply the rotation during processing:
// sharp automatically applies EXIF orientation
sharp("photo.jpg")
.rotate() // Auto-rotate based on EXIF
.resize(800)
.toFile("output.jpg");
Color Profiles and Consistency
Images may embed ICC color profiles (sRGB, Adobe RGB, Display P3). When the color profile is missing or mismatched, colors can shift between devices and browsers.
For the web, sRGB is the universal standard. Convert images to sRGB during processing to ensure consistent colors:
sharp("input.jpg")
.toColorspace("srgb")
.withIccProfile("srgb")
.toFile("output.jpg");
File Size Breakdown
Metadata can account for a surprising portion of small images:
| Component | Typical Size |
|---|---|
| EXIF data | 5-50 KB |
| ICC profile | 2-5 KB |
| IPTC/XMP | 1-10 KB |
| Embedded thumbnail | 5-30 KB |
| Total metadata | 13-95 KB |
For a 100 KB thumbnail, metadata might represent 30-50% of the file size. Stripping it is a meaningful optimization.
Useful Metadata for Developers
Not all metadata should be removed. Some is actively useful:
- Width and height help browsers reserve space before the image loads, preventing layout shift.
- Color profile ensures accurate rendering.
- DPI matters for print output (web images are typically 72 or 96 DPI).
When stripping metadata, consider preserving the color profile and explicitly setting dimensions in your HTML.
Inspecting Metadata Quickly
Before diving into code, you can inspect metadata from the command line:
# Full EXIF dump
exiftool image.jpg
# Just GPS coordinates
exiftool -gpslatitude -gpslongitude image.jpg
# File format details
file image.jpg
identify -verbose image.jpg # ImageMagick
Try our Image Viewer to inspect image metadata, dimensions, and format details instantly — right in your browser, no upload required.