Photo Metadata Privacy Toolkit -- scan, clean, redact, and export EXIF data
Project description
Pheser
Photo Metadata Privacy Toolkit -- scan, clean, redact, compare, and export EXIF metadata from images.
pip install pheser
Features
| Feature | Description |
|---|---|
| Scan | Full EXIF dump with privacy risk score (0-100) and Google Maps link for GPS |
| Clean | Remove GPS only, all EXIF, specific tags, or keep-only-safe-tags mode |
| Remake | Recreate metadata with custom Make/Model/DateTime/GPS values |
| Redact | Spoof GPS coordinates, randomize timestamps, replace device info |
| Compare | Diff EXIF between two images (before/after verification) |
| Batch | Process entire directories recursively with any operation |
| Export | Save scan results as JSON, CSV, or plain-text report |
Orientation and display geometry tags are always preserved -- your image will never be rotated by Pheser.
Installation
pip install pheser
Requirements: Python 3.11+, Pillow >= 10.0, piexif >= 1.1.3
CLI
Scan
pheser scan photo.jpg
pheser scan photo.jpg --export report.json --fmt json
pheser scan photo.jpg --export report.csv --fmt csv
pheser scan photo.jpg --no-hash --no-risk
Clean
# Remove GPS only (default)
pheser clean photo.jpg
# Strip ALL EXIF
pheser clean photo.jpg --mode all
# Remove specific tags
pheser clean photo.jpg --mode tags --tags Make Model Software
# Keep only safe tags (removes GPS + device serials + owner info)
pheser clean photo.jpg --mode keep_basic -o safe_photo.jpg
Remake
pheser remake photo.jpg --make Sony --model "Alpha 7" --artist "Jane Doe"
pheser remake photo.jpg --inject-gps 48.8584 2.2945
Redact (Spoof)
# Replace GPS with random coordinates
pheser redact photo.jpg --random-gps
# Spoof exact location
pheser redact photo.jpg --spoof-gps 51.5074 -0.1278
# Randomize everything
pheser redact photo.jpg --random-gps --random-datetime --spoof-device Apple "iPhone 15"
Compare
pheser compare original.jpg cleaned.jpg
Batch
pheser batch ./photos --op clean-gps --out-dir ./photos_clean
pheser batch ./photos --op redact-random --recursive
pheser batch ./photos --op clean-all --dry-run
Python API
from pheser import scan, clean, redact, remake, batch_process
from pheser.compare import compare
from pheser.exporter import export_report
# Scan
results = scan("photo.jpg", raw=True)
print(results["risk_score"]) # 0-100
print(results["gps"]) # {"latitude": ..., "maps_url": ...}
# Clean GPS
clean("photo.jpg", mode="gps")
# Strip all EXIF
clean("photo.jpg", mode="all", output_file="stripped.jpg")
# Remove specific tags
clean("photo.jpg", mode="tags", remove_tags=["Make", "Model", "Software"])
# Keep only safe metadata
clean("photo.jpg", mode="keep_basic")
# Spoof GPS + randomize datetime
redact("photo.jpg", randomize_gps=True, randomize_datetime=True)
# Inject fake GPS
redact("photo.jpg", spoof_gps=(35.6762, 139.6503)) # Tokyo
# Recreate with custom values
remake("photo.jpg", make="Fujifilm", model="X100V", artist="John")
# Compare two files
diff = compare("before.jpg", "after.jpg")
# Export scan report
results = scan("photo.jpg", raw=True)
export_report(results, "report.json", fmt="json")
export_report(results, "report.csv", fmt="csv")
export_report(results, "report.txt", fmt="txt")
# Batch process a folder
batch_process(
"photos/",
lambda src, dst: clean(src, dst, mode="gps", verbose=False),
out_dir="photos_clean/",
recursive=True,
)
Privacy Risk Score
| Score | Label | Meaning |
|---|---|---|
| 0 | Safe | No sensitive metadata |
| 1-19 | Low | Minor device info only |
| 20-49 | Medium | Device + timestamps present |
| 50-100 | High | GPS location data found |
Supported Formats
.jpg / .jpeg -- .tiff / .tif -- .webp
License
MIT -- Copyright (c) 2025 AzzTE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pheser-1.0.0.tar.gz.
File metadata
- Download URL: pheser-1.0.0.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb9e801ca5b0d12c2e1c22042f8dd4b55beb012577a695817e47e74144f1992b
|
|
| MD5 |
3ad792f877e33fe14093991a52d5c86a
|
|
| BLAKE2b-256 |
3cab8206ec4e6a1eec2a50e2b7428cb34276af2a88923e9917e73b2b643144f8
|
File details
Details for the file pheser-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pheser-1.0.0-py3-none-any.whl
- Upload date:
- Size: 19.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08d677bdf8c2c9f4d68cdd1e4d7a71f69d02bcddc4d94b8d2ca78f7dd5bafca7
|
|
| MD5 |
b1cd18f20107220fb31e58baf3b1df6b
|
|
| BLAKE2b-256 |
8368c16c9afdd7b7ec63ef90b0762ba32a6705e9cda85d02bcccd95c7eda187a
|