A common way location leaks: you post a photo of your cat to a forum that serves the original file. The phone that took the picture wrote GPS coordinates into the file, and the forum passed the bytes through unchanged. Anyone who drops the image into a free EXIF viewer can read them.

Open the EXIF Metadata Viewer →

EXIF is the side of digital photography most people never see. This guide covers what is actually in the metadata block, why it is there, what social platforms do or do not strip on upload, and how to inspect and remove it without uploading anything to a server.

What EXIF Actually Contains

EXIF (Exchangeable image file format) is a standard maintained by CIPA and JEITA (current version Exif 3.0, CIPA DC-008-2023) that defines how cameras and phones embed structured metadata into image files. Version 1.0 was published in 1995, and camera and phone JPEGs carry it by default.

A typical phone-camera photo carries far more than a date stamp:

FieldExampleWhy it is therePrivacy risk
Make / ModelApple / iPhone 15 ProCamera identificationLow — common across millions of devices
LensModeliPhone 15 Pro back camera 6.86mm f/1.78Optical info for editorsLow
DateTimeOriginal2024-08-12 14:32:08Sorting and album organizationMedium — reveals when you were where
FNumber / ExposureTime / ISO / FocalLengthf/1.8, 1/120s, ISO 80, 24mmReproducing exposure in editorsNone
GPSLatitude / GPSLongitude31.230556° N, 121.473611° EGeotagging for maps and searchHigh — pinpoints location to a few meters
GPSAltitude15 mAltitude above sea levelMedium
SoftwareiOS 18.1, Photoshop 25.4Edit historyLow to medium — leaks workflow
SerialNumber (some bodies)E.g. Sony / Canon DSLRCamera-body identityHigh for journalists
ImageUniqueIDUUID per shutter pressDeduplicationMedium

Two other metadata standards commonly travel inside JPEG application marker segments:

  • XMP (Adobe’s XML metadata) — captures Lightroom edit history, ratings, captions, copyright fields. Stored in an APP1 segment alongside or instead of EXIF.
  • IPTC — older newsroom standard for caption, author, and copyright. Stored in an APP13 segment.

A photo from a phone often has all three: EXIF for capture parameters in APP1, XMP for any editing in another APP1, and sometimes IPTC stamped into APP13 by a desktop tool.

The JPEG Layout — Why Strip Mode Does Not Re-encode

A JPEG is not one continuous blob. It is a stream of marker segments, each starting with 0xFF followed by a marker byte:

0xFFD8           SOI    Start of Image
0xFFE0           APP0   JFIF density and aspect
0xFFE1           APP1   EXIF or XMP   ← personal data lives here
0xFFE1           APP1   XMP (a second one is common)
0xFFE2           APP2   ICC color profile
0xFFED           APP13  Photoshop / IPTC
0xFFEE           APP14  Adobe color transform marker
0xFFDB × 2       DQT    Quantization tables
0xFFC0           SOF    Start of Frame (image dimensions)
0xFFC4 × 4       DHT    Huffman tables
0xFFDA           SOS    Start of Scan (compressed pixel data follows)
...              compressed entropy-coded image data
0xFFD9           EOI    End of Image

The pixel data lives between the SOS marker and the EOI marker. Everything before SOS is metadata or decoder configuration. To strip metadata, you do not need to touch pixels at all — you walk the marker stream and drop the segments that carry personal data, then concatenate what is left.

The ZeroTool stripper drops three markers:

  • APP1 (0xFFE1) — EXIF and XMP
  • APP13 (0xFFED) — Photoshop / IPTC
  • APP14 (0xFFEE) — Adobe color transform

It keeps SOI, APP0 (JFIF), APP2 (ICC color profile, so colors render the same), all DQT / SOF / DHT segments, the SOS marker, the compressed image bytes, and EOI.

The result is byte-identical to the original on the pixel side. No quality loss. No re-encoding. Two side effects follow from dropping whole segments: the EXIF Orientation tag goes with APP1, so a phone photo that relied on it can display rotated; and APP14 tells decoders how to interpret Adobe CMYK / YCCK JPEGs, so such files can render with wrong colors after the strip. Ordinary RGB photos from phones and cameras do not depend on APP14. Compare this to the common “drop EXIF by re-encoding through Canvas” pattern:

// LOSSY — re-encodes JPEG through Canvas, quality drops
canvas.getContext('2d').drawImage(img, 0, 0);
canvas.toBlob(blob => save(blob), 'image/jpeg', 0.95);

Canvas re-encoding is one line and works in any browser, but every save is a fresh JPEG quantization. After three round-trips, edges visibly soften and chroma blocks show up in flat colors. The byte-level approach has none of that — the cleaned file is the same compressed pixels, just with the personal-data segments cut out.

GPS Coordinates — From Rationals to Decimal Degrees

The EXIF spec stores GPS coordinates in a peculiar format: three rational numbers (degrees, minutes, seconds), each itself a numerator-denominator pair, plus a one-character reference (N, S, E, W).

A real example:

GPSLatitudeRef:  N
GPSLatitude:     31/1, 13/1, 50/1
GPSLongitudeRef: E
GPSLongitude:    121/1, 28/1, 25/1

Decoded:

latitude  = 31 + 13/60 + 50/3600 = 31.230556° N
longitude = 121 + 28/60 + 25/3600 = 121.473611° E

Real-world precision depends on two things: the rational denominators the camera writes (a denominator of 1 means whole-second resolution, around 30 m at the equator; phones often use much larger denominators for sub-second precision) and the underlying GPS fix quality. Phones writing high-denominator rationals on a clean sky-view fix can encode coordinates accurate to a few meters. The viewer only converts what is in the file — it cannot improve or worsen the underlying fix.

The viewer decodes both axes, applies the S / W sign flip, and constructs a Google Maps URL locally. The link only fires a request when you click it — until then no third party sees the coordinate.

What Social Platforms Actually Strip

A common assumption is “I posted on a big platform, the photo is safe.” Most platforms do not document what they keep, the behavior differs between the image shown to other users and the copy kept on the server, and it changes between app versions and upload paths (compressed photo vs. “original” vs. file attachment). Two things hold regardless of platform: a file sent as an attachment (email, chat “send as file”, issue trackers that serve the uploaded file) usually arrives byte for byte, and a platform that keeps the original on its servers still has your location even if other users cannot see it.

You can check a specific path yourself: upload a test photo that has GPS data, download it back the way another user would, and open the downloaded file in the viewer. Or strip locally before posting and the question disappears.

Common Edge Cases

”No EXIF found” on a phone photo

If the photo has been screenshotted, exported through certain edit apps, or converted from HEIC to JPEG by some pipelines, the EXIF block can be entirely missing. The viewer will say “No EXIF metadata found” — which is the desired state. You can still run the strip pass to remove any XMP or IPTC blocks the editor added.

EXIF still present after Photoshop “Save for Web”

“Save for Web” with metadata set to None removes EXIF but typically leaves the ICC profile and may add an XMP block describing the export. The ZeroTool viewer reads EXIF only; to inspect XMP contents use an XMP-aware tool such as exiftool -xmp:all. The strip pass still removes the XMP APP1 segment regardless.

HEIC / HEIF photos

HEIC is the default container on iPhone since 2017. HEIC carries EXIF in a different (ISOBMFF) structure, not as a JPEG marker. The ZeroTool tool is JPEG-only by design. To strip HEIC EXIF, use exiftool -all= file.heic locally, or convert HEIC to JPEG first and then strip.

TIFF, HEIC, PNG files

TIFF stores EXIF in IFD trees similar to the EXIF block inside a JPEG, but the file is not a JPEG marker stream. PNG can carry an eXIf chunk per the 2017 spec extension. The ZeroTool tool is scoped to JPEG by design — for other formats use exiftool -all= locally or convert to JPEG first.

Files larger than 25 MB

The tool reads the whole file into memory. It shows a warning above 25 MB and refuses files above 100 MB; phones may run short of memory before that. For batch jobs over many large files, a local CLI like exiftool -all= or mat2 is the right tool.

Reproducing the Strip with Other Tools

The ZeroTool strip is a JavaScript implementation of a 30-line algorithm. Here is the same operation in three other environments.

Bash with exiftool — the canonical command-line tool, written in Perl and distributed under Perl’s own license (dual Artistic / GPL):

# Remove ALL metadata (EXIF, XMP, IPTC, ICC) — note: removing ICC may shift colors
exiftool -all= photo.jpg

# Keep ICC color profile, drop EXIF / XMP / IPTC only
exiftool -all= --icc_profile:all photo.jpg

# Verify what is left (exiftool keeps a backup as photo.jpg_original)
exiftool photo.jpg

Python with Pillow (re-encodes):

from PIL import Image

# This re-encodes — minor quality loss
img = Image.open("photo.jpg")
img.save("photo-clean.jpg", "JPEG", quality=95, optimize=True)

Python with piexif (no re-encode):

import piexif

# Walks the marker stream, removes EXIF only
piexif.remove("photo.jpg")

Browser JavaScript — what the ZeroTool tool does internally:

async function stripJpegMetadata(file) {
  const buf = await file.arrayBuffer();
  const view = new DataView(buf);
  if (view.getUint16(0) !== 0xFFD8) throw new Error("not a JPEG");

  const keep = [[0, 2]];                  // SOI
  let pos = 2;
  while (pos < view.byteLength - 1) {
    const marker = view.getUint16(pos);
    if (marker === 0xFFDA || marker === 0xFFD9) {
      keep.push([pos, view.byteLength]);  // SOS through EOI
      break;
    }
    if ((marker & 0xFF00) !== 0xFF00) break;
    const segLen = view.getUint16(pos + 2);
    const segEnd = pos + 2 + segLen;
    if (marker !== 0xFFE1 && marker !== 0xFFED && marker !== 0xFFEE) {
      keep.push([pos, segEnd]);
    }
    pos = segEnd;
  }

  const total = keep.reduce((s, r) => s + r[1] - r[0], 0);
  const out = new Uint8Array(total);
  let off = 0;
  for (const [a, b] of keep) {
    out.set(new Uint8Array(buf, a, b - a), off);
    off += b - a;
  }
  return new Blob([out.buffer], { type: "image/jpeg" });
}

That snippet is the entire algorithm. The rest of the tool is the EXIF reader for the inspection panel.

How the ZeroTool Tool Compares

ZeroTool is one of many EXIF tools — what is different here:

CapabilityZeroToolexiftool (CLI)
Runs locally, no uploadYes, in the browser tabYes, on your machine
Strips without re-encodingYes (drops APP1 / APP13 / APP14)Yes (rewrites metadata only)
Open-source codeYes (repo)Yes
GPS map linkYesNo (prints coordinates)
FormatsJPEG onlyJPEG, HEIC, TIFF, PNG, video and more
BatchNo (one file at a time)Yes (directories, -r)

For a one-off “is there EXIF in this and can I strip it” check, the browser tool does the job without installing anything. For batches or HEIC files, exiftool is the right tool.

Privacy Notes

  • The page does not upload your photos. Photo bytes stay in the browser tab. Because photos can carry location data, this tool page loads neither Google Analytics nor AdSense.
  • The Google Maps deep link is constructed locally. It does not fire a request until you click it.
  • The cleaned-file download is a Blob URL revoked after a second to avoid leaks in the page memory.

Further Reading

Strip EXIF from a photo now →