How to Extract EXIF Data from a Photo
Every photo taken with a digital camera or smartphone contains hidden metadata called EXIF data. It records the camera model, shutter speed, aperture, ISO, focal length, the exact time the photo was taken, and — if location services were on — GPS coordinates accurate to within a few meters.
Here's how to read it.
What EXIF data looks like
A typical JPEG from a smartphone contains fields like:
| Field | Example value |
|---|---|
| Make | Apple |
| Model | iPhone 15 Pro |
| DateTime | 2025:09:14 14:32:05 |
| ExposureTime | 1/120 |
| FNumber | f/1.8 |
| ISO | 64 |
| FocalLength | 6.86 mm |
| GPSLatitude | 40° 42' 46" N |
| GPSLongitude | 74° 0' 21" W |
| Software | iOS 18.0 |
The GPS coordinates in this example point to Lower Manhattan. If you post a photo taken at home, that EXIF data goes with it unless you strip it first.
Reading EXIF in the browser (no software needed)
Browser-based EXIF viewers parse the image locally without uploading it. Drag in a photo, and the tool displays all the embedded metadata. No account, no install, no data sent anywhere.
This is the fastest option for one-off lookups — checking the coordinates of a photo, confirming a timestamp, or verifying camera settings.
Reading EXIF in Python with Pillow
The Pillow library reads EXIF data from JPEG and TIFF files.
from PIL import Image
from PIL.ExifTags import TAGS
def read_exif(path: str) -> dict:
img = Image.open(path)
raw_exif = img._getexif()
if not raw_exif:
return {}
return {TAGS.get(tag, tag): value for tag, value in raw_exif.items()}
exif = read_exif("photo.jpg")
for key, value in exif.items():
print(f"{key}: {value}")
Extracting GPS coordinates
GPS data is stored as a nested structure in EXIF. Here's how to decode it into decimal degrees:
from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS
def get_gps_coordinates(path: str):
img = Image.open(path)
raw_exif = img._getexif()
if not raw_exif:
return None
# Find the GPSInfo tag (tag number 34853)
gps_info = None
for tag, value in raw_exif.items():
if TAGS.get(tag) == "GPSInfo":
gps_info = {GPSTAGS.get(t, t): v for t, v in value.items()}
break
if not gps_info:
return None
def to_decimal(dms, ref):
degrees, minutes, seconds = dms
decimal = float(degrees) + float(minutes) / 60 + float(seconds) / 3600
if ref in ("S", "W"):
decimal = -decimal
return decimal
lat = to_decimal(gps_info["GPSLatitude"], gps_info["GPSLatitudeRef"])
lon = to_decimal(gps_info["GPSLongitude"], gps_info["GPSLongitudeRef"])
return lat, lon
coords = get_gps_coordinates("photo.jpg")
if coords:
lat, lon = coords
print(f"https://maps.google.com/?q={lat},{lon}")
ExifTool (command line)
ExifTool by Phil Harvey is the most comprehensive EXIF reader available. It handles hundreds of formats — JPEG, TIFF, RAW formats, video, PDF, and more.
# Install
brew install exiftool # macOS
sudo apt install libimage-exiftool-perl # Ubuntu/Debian
# Read all metadata from a file
exiftool photo.jpg
# Read specific fields
exiftool -DateTimeOriginal -GPSLatitude -GPSLongitude photo.jpg
# Extract EXIF from all JPEGs in a folder
exiftool -r /path/to/folder
# Output as JSON
exiftool -json photo.jpg
# Strip ALL metadata (privacy)
exiftool -all= photo.jpg
Stripping EXIF data for privacy
If you're sharing photos publicly and don't want to expose GPS coordinates or device info:
# ExifTool: strip everything
exiftool -all= photo.jpg
# Strip but keep the original (saves photo_original backup)
exiftool -all= -overwrite_original photo.jpg
In Python with Pillow:
from PIL import Image
import io
def strip_exif(input_path: str, output_path: str):
img = Image.open(input_path)
# Create new image from pixel data only — no EXIF
clean = Image.new(img.mode, img.size)
clean.putdata(list(img.getdata()))
clean.save(output_path)
Which files contain EXIF?
| Format | EXIF support |
|---|---|
| JPEG | Yes — most common |
| TIFF | Yes |
| PNG | No (uses different metadata: iTXt chunks) |
| HEIC/HEIF | Yes (modern iPhone format) |
| WebP | Limited (basic Exif chunk) |
| RAW (CR2, NEF, ARW) | Yes — extensive camera data |
| No EXIF (has XMP metadata instead) | |
| Video (MP4, MOV) | Not EXIF, but contains creation time + GPS in separate atoms |
Key takeaways
- EXIF data is embedded in JPEG/TIFF files and records camera settings, timestamps, and GPS coordinates.
- Browser tools parse files locally — no upload required for sensitive photos.
- Python's Pillow handles basic EXIF; use ExifTool for comprehensive extraction across all formats.
- GPS coordinates in EXIF are accurate enough to identify a home address — strip before sharing if privacy matters.
- PNG files don't use EXIF; look for iTXt or tEXt chunks instead.