A JPEG can state its size in three places, and after an edit they often disagree. Only one describes the pixels you actually have: the frame header the decoder reads.
| Where | ExifTool name | Tag ID |
|---|---|---|
| JPEG SOF marker | File:ImageWidth, File:ImageHeight | none |
| IFD0 | EXIF:ImageWidth, EXIF:ImageHeight | 0x0100, 0x0101 |
| ExifIFD | ExifImageWidth, ExifImageHeight | 0xA002, 0xA003 |
The Exif specification calls the last pair PixelXDimension and PixelYDimension; ExifTool renames them. In a TIFF, IFD0 ImageWidth is the real raster width. In a camera JPEG the IFD0 pair is normally absent, and the true size comes from the SOF (start of frame) segment.
Why they disagree after a resize
Most resizers copy the EXIF block and never touch it. A 3840x2160 file after convert -resize 1920x1080 in ImageMagick 6.9:
[File] ImageWidth : 1920
[File] ImageHeight : 1080
[ExifIFD] ExifImageWidth : 3840
[ExifIFD] ExifImageHeight : 2159
[Composite] ImageSize : 1920x1080
[Composite] Megapixels : 2.1Two lies in one file. The EXIF pair still describes the original, and the source had already recorded 2159 for a 2160-pixel height. ExifTool's Composite:ImageSize and Megapixels come from the File values, so trust those. With -n they print as 1920 1080 and 2.0736.
Orientation doesn't change any of these numbers: a portrait shot stored as 1200x800 with Orientation 6 still reports 1200x800.
Editing them
The EXIF reader shows EXIF:ImageWidth and ImageHeight, and the editor can write them for JPEG and TIFF. On a JPEG that changes a label and nothing else. On a TIFF, leave them alone: the decoder uses ImageWidth to cut the strips into rows. Setting a 1200-pixel-wide test TIFF to 1000 with ExifTool produced only a minor warning ("Oversized IFD0 StripByteCounts"), and the file then decoded as 1000x800 diagonal stripes.
To correct stale EXIF dimensions on a JPEG:
exiftool -ExifImageWidth=1920 -ExifImageHeight=1080 photo.jpgThe EXIF data guide explains how IFD0 and the ExifIFD fit together.