A photograph off a phone is around four megabytes. Twenty or thirty kilobytes of that is not the picture. It is a block of tags the camera wrote before it saved the file: the model of the phone, the lens, the shutter speed, the exact second the shutter fired, and, if location services were on for the camera, a latitude and a longitude good to a few metres.
That block travels with the file. Send it by email, drop it in a shared folder, attach it to a forum post, and the coordinates go along. Somebody photographs a bicycle in the hallway to sell it. The picture shows a bicycle. The file says which front door the bicycle is behind.
Most of the time none of this matters, and some of it is genuinely useful: f/1.8 at 1/60 and ISO 3200 explains why an indoor shot came out noisy. The difficulty is that you cannot see any of it. The file opens as a picture and says nothing about itself.
If you run a WordPress site there is a companion piece here on what WordPress reads on upload and what it keeps, and this article does not repeat it. This one is about the file itself: what the fields mean, where in the bytes they sit, which program wrote which of them, and how to read the lot yourself.
Start with one of your own photos
Drop a JPEG below. It is parsed inside the page you are reading, by JavaScript, on your machine: the file is never uploaded and the tool makes no network request of any kind. Pick something straight off a phone rather than a picture that has already been through a chat app, because the interesting version is the one nobody has cleaned up yet.
EXIF viewer
Open a photo and read what it carries: camera, lens, settings, dates, and the spot on the map where the shutter fired. Drop a whole folder of them in and strip the lot in one go, losslessly, by rewriting the container instead of encoding the picture again. Every file is read here in the browser tab and none of them is ever uploaded.
or press Enter to choose them. One to read in detail, or many to clean at once. JPEG, PNG, WebP and TIFF.
Nothing loaded yet.
The picture is drawn from your own disk. Nothing about it is sent anywhere.
Drop a photo above to see its tags.
This photo says where it was taken. Anyone you send the file to can read the same spot, often to within a few metres. Strip it before you post a picture of your home, your child’s school or your workplace.
Nothing here contacts a map service. The link only opens a map if you copy it and paste it into a browser yourself.
Camera and lens, exposure settings, the date and time the shutter fired, the editing software, the author and copyright line, and the GPS position if the camera stored one. Every value is shown next to its raw EXIF tag id, so you can look any of them up.
Each one is cleaned by rewriting the container, not by encoding the picture again, so the compressed image data comes through byte for byte and only the metadata changes. JPEG, PNG and WebP. Nothing is uploaded.
A colour profile says nothing about you, and without it colours shift on wide gamut photos. Keeping the picture upright writes back one single tag and nothing else, because a phone stores the rotation in EXIF rather than in the pixels: take that away with the rest and the photo ends up on its side.
| File | Format | Before | After | Taken out | Note |
|---|
Cleaning is lossless on JPEG, PNG and WebP: the file is walked segment by segment and only the metadata segments are dropped, so every byte of compressed image data survives and the picture is pixel for pixel the one you started with. A TIFF cannot be treated that way, because in a TIFF the metadata structure is the file, and a GIF has no EXIF to begin with. For those two the older route is still there: the picture is drawn onto a canvas and encoded again, which does cost a little quality.
Three stores, three jobs
People say EXIF when they mean metadata. EXIF is only one of at least three separate stores a JPEG can carry, and none of them knows the others exist.
EXIF is written by the camera at the moment of capture. Its structure is borrowed from TIFF: numbered tags in tables, each one a small machine fact. Exposure time, aperture, ISO, focal length, flash state, orientation, three separate timestamps, and on a phone a sub-table of GPS values. Nothing in it is prose.
IPTC came out of the news wire business decades before digital cameras and holds the opposite kind of thing: creator, credit line, copyright notice, caption, headline, keywords. A picture desk fills it in, or a photographer does through an editor’s File Info panel. It sits inside a Photoshop resource block, which is why it often gets called the Photoshop metadata.
XMP is an XML document, introduced by Adobe in 2001 as the successor to both. It carries rights and licence statements, edit history, keywords and increasingly alt text. Lightroom and Photoshop both write it, and it usually duplicates the other two rather than replacing them.
A fourth passenger is not metadata about the photograph at all: the embedded ICC colour profile, which tells a viewer what the numbers in the pixels mean. Strip that and the picture itself changes, which is the mechanism behind images that come out washed out after processing. Remove any one of the four and the other three sit exactly where they were. Software that reports “metadata removed” has usually removed one of them.
Where the bytes actually sit
A JPEG is a chain of segments. Each starts with 0xFF, then a marker byte, then for most markers a two byte big endian length that counts itself, so a parser walks the chain by reading a length and jumping that far forward. The metadata blocks are application segments, APP0 to APP15, told apart not by the marker but by an identifier string sitting immediately after it.
FF D8 SOI, start of image
FF E1 LL LL APP1
45 78 69 66 00 00 "Exif "
49 49 2A 00 TIFF header: "II", then the number 42
08 00 00 00 offset of IFD0, counted from the "II"
FF E1 LL LL a second APP1
68 74 74 70 ... "http://ns.adobe.com/xap/1.0/ " then XMP
FF ED LL LL APP13: "Photoshop 3.0 ", 8BIM 0x0404, IPTC
FF E2 LL LL APP2: "ICC_PROFILE ", the colour profile
FF DB ... quantisation tables
FF C0 ... frame header: dimensions and components
FF DA ... start of scan, then the picture data
FF D9 EOI
EXIF and XMP share a marker and are separated only by that identifier. After the six bytes spelling Exif and two nulls, the block stops being JPEG at all and becomes a complete small TIFF file, header included.
The first two bytes of that header are the byte order: II for Intel, little endian, MM for Motorola, big endian. Canon bodies write II, Nikon bodies write MM, and both are legal. Then the number 42, present purely so a parser can confirm it guessed right, then a four byte offset to the first image file directory. An IFD is an array: two bytes of entry count, that many twelve byte entries, then four bytes pointing at the next IFD or four zeroes.
0A 00 IFD0 entry count, 10 entries follow
12 01 tag id 0x0112, Orientation
03 00 type 3, SHORT
01 00 00 00 count 1 value
06 00 00 00 value 6
0F 01 tag id 0x010F, Make
02 00 type 2, ASCII
06 00 00 00 count 6 bytes, "Apple" plus a null
92 00 00 00 offset too long for four bytes, so
the string sits at byte 146
Anything that fits in four bytes is stored in the entry. Anything longer, a model name, a rational, a GPS coordinate (three rationals, twenty four bytes), is replaced by an offset counted from the start of the TIFF header rather than the file. Two entries in IFD0 are pointers by design: 0x8769 leads to the Exif IFD, where exposure and lens data live, and 0x8825 leads to the GPS IFD. The next-IFD pointer at the end of IFD0 usually leads to IFD1, which describes an embedded thumbnail, often 160 by 120, stored as a separate little JPEG.
That thumbnail is worth knowing about. It is generated once and some editors never refresh it, so a cropped picture can still carry a thumbnail of the uncropped original. People have published a crop and shipped the thing they cropped out inside the same file.
One APP1 segment holds at most 65,533 bytes, because the length field is two bytes and counts itself. That is the ceiling on how much EXIF a file can carry, and why a long XMP document spills into a second segment.
Camera fields and editor fields
A tag list gets much easier to read once you know who put each line there. The camera writes the physics: Make (0x010F), Model (0x0110), ExposureTime (0x829A), FNumber (0x829D), ISOSpeedRatings (0x8827), FocalLength (0x920A), the 35 mm equivalent (0xA405), the flash state (0x9209), the orientation flag, and the whole GPS sub-table. Many bodies add a serial number (0xA431) and a lens serial number (0xA435).
The editing software writes a different set. Software (0x0131) names the last program to save the file, so a phone JPEG says the iOS version and a processed one says Lightroom. DateTime (0x0132) is not when the photo was taken, it is when the file was last written. Artist (0x013B) and Copyright (0x8298) come from a preset in an editor, essentially never from a camera. Rights fields filled and shutter data missing means you are looking at a file that has been through a pipeline.
The dates trip people up because there are three. DateTimeOriginal (0x9003) is when the shutter fired. DateTimeDigitized (0x9004) is when the image became digital, identical to the first on a digital camera, quite different on a scan of a print. DateTime (0x0132) is the last save. All three use the same fixed twenty byte string, colons in the date, a null on the end: 2026:08:14 19:32:07. There is no time zone in that. Exif 2.31, published in 2016, added offset tags (0x9010 to 0x9012), but older files carry a wall clock reading and nothing else, so 19:32 could be Berlin or Buenos Aires and the file will not say.
Orientation is a number, not a rotation
Turn a phone on its side and the sensor does not turn with it. Pixels come off it in the same order they always do, and rewriting them upright would mean decoding and re-encoding the JPEG on the spot. So the camera does the cheap thing: it reads the accelerometer and writes one number into tag 0x0112, type SHORT, one of eight legal values.
A viewer that reads the flag turns the picture before drawing it. A viewer that ignores it draws the picture as stored, lying on its side. Nothing is wrong with the file in either case, which is why the same photo is upright in one program and sideways in another, and why that argument never resolves.
Browsers were on the wrong side of this and are now on the right one. CSS Images Level 3 made image-orientation: from-image the initial value, and Chrome, Firefox and Safari all honour the flag for a plain <img>. Desktop file managers and older viewers are the usual holdouts.
There is a useful consequence for the tool above. A canvas draws the picture the browser already decoded, and the browser decoded it the right way up, so a canvas re-encode bakes the rotation into the pixels and the flag disappears with the rest. The output then looks correct everywhere, including in the programs that never read the flag.
WordPress handles this on its own terms, and the detail surprises people: since 5.3, wp_create_image_subsizes() calls maybe_exif_rotate(), and if the flag says rotate, core saves a new file with -rotated appended, promotes it to be the working original through _wp_image_meta_replace_original(), and sets the stored orientation to 1. The file you actually uploaded stays on disk exactly as it was, flag and all.
The privacy part, stated plainly
If the camera app has location permission, a phone writes latitude, longitude, their hemisphere references and usually an altitude into every photo. Accuracy outdoors is a handful of metres. A picture taken in a living room therefore carries the living room’s position.
Nothing bad happens most of the time. The cases where something does are all ordinary: a marketplace listing photographed at home, an image posted into a public forum thread, an attachment sent to somebody you later stop trusting. The data does not announce itself, and that is the whole problem. You cannot make a decision about a thing you cannot see.
The serial numbers are the quieter half. Two photos with no names, no faces and no coordinates still prove they came off the same body if both carry the same BodySerialNumber. That is a link, and links are what matter.
When the tool above finds coordinates it says so in plain words, prints them in decimal, and offers an OpenStreetMap URL in a read-only field with a Copy button rather than as a link. That is deliberate. Following a link would hand the location to a map service the moment you clicked, which is a strange way to demonstrate a privacy problem.
What strips metadata without asking
Plenty of software removes this data as a side effect of doing something else, which is why a photo you know had coordinates sometimes turns up with none.
- Most social platforms. They re-encode on upload for their own size and quality targets, and the metadata goes with the old file. Treat that as a side effect, not a privacy feature: the platform read every tag before it dropped them.
- Image optimisation plugins and services. Nearly all have a strip metadata or remove EXIF switch, and several ship with it on. The same switch usually takes the ICC profile too, which is a separate and far more visible problem.
- Format conversion. Going from JPEG to WebP or AVIF carries nothing across unless the converter is told to copy it, and many are not. Worth knowing before you convert a library to WebP and assume the copyright fields came along.
- Any canvas re-encode, including the download button in the tool above. A canvas holds pixels and nothing else, so whatever comes out of it starts clean.
- Screenshots. A screenshot of a photograph has no EXIF whatsoever. Crude, lossy and completely effective.
The one case for keeping it
All of those remove everything, including the fields you might have wanted. If you publish photographs you want credited, the rights fields are the only claim that travels with the file after it leaves your site: a right click and save takes the pixels and the metadata together. EXIF Artist and Copyright, the IPTC creator and copyright notice, and the XMP rights statement are all readable by anyone downstream who looks, and by software that looks automatically.
Google Images is the concrete example. Its licence panel is populated from IPTC photo metadata, specifically the web statement of rights and the licensor URL, so a filled licence field can put a visible link on a picture in search results. Note what kind of feature that is: a display behaviour driven by fields you filled in, not a ranking signal. EXIF as an SEO lever remains folklore, and the two are picked apart in what actually works in WordPress image SEO.
So the workable position is not strip everything or keep everything. It is: strip the location, strip the serial numbers, keep the rights fields. That needs a tool that edits selectively, which the one above deliberately is not.
Where this tool stops
It decodes the tags a person actually reads, not every tag in the file, and the ones it does not name are counted rather than hidden: the status line says something like “31 tags read, 6 more left out. Location included.” It does not decode UserComment, it does not decode maker notes (each manufacturer’s private, undocumented block, frequently the largest single thing in the EXIF), and it does not decode XMP. TIFF is parsed but no browser can draw it, so for those files the preview and the download are switched off and the tool says why.
The download is a re-encode, not a rewrite. The picture is drawn to a canvas at its natural size and encoded again at quality 0.92, so grain and fine detail shift and the file size changes. What goes is total: EXIF, GPS, the embedded thumbnail, maker notes and the colour profile. That is the right trade for one photo you are about to send to a stranger and the wrong one for an archive master.
For a removal that leaves the compressed picture data byte for byte identical, you want something that rewrites the segments instead of the pixels. On the command line that is exiftool.
# every metadata block gone, pixels untouched
exiftool -all= photo.jpg
# only the location, everything else kept
exiftool -gps:all= photo.jpg
# read the whole file: every tag, grouped, with names
exiftool -a -G1 -s photo.jpg
And once the question stops being one file and starts being a few thousand already sitting in a media library, it is not a viewer problem at all. That is the ground WunderPaint’s media library manager works on: folders, tags, usage, duplicates and stored metadata across the whole library, so you can see the shape of what you have before deciding what to do to it.
A habit worth having
The useful shift is not learning tag numbers. It is getting into the habit of asking, before a photograph leaves your machine, whether you know what is inside it. Almost nobody does, because nothing in the normal path of taking a picture and sending it ever shows you. Look at two or three of your own files and the categories become obvious: the exposure block is harmless, the software and date block is mildly revealing, the serial numbers are a fingerprint, and the GPS block is an address.
From there the decisions are easy, and they differ by situation rather than by principle. A photo for a marketplace listing gets stripped. A photo for a client archive keeps everything, because the exposure data is the point. A portfolio image keeps the rights fields and loses the location.
What makes it worth the two seconds is the asymmetry. Reading the data costs nothing and happens in a browser tab that never talks to a server. Not reading it also costs nothing, right up until the one file where it costs a great deal, and by then the file is somewhere you cannot reach.