This release is a pre-release and may not be stable for production use.
Blurry
Cover faces and strip metadata from photos and videos,
on your own computer, with no network.
⬇ Download for Mac
·
Windows and Linux
Version 0.1.1 · Mac with Apple Silicon, macOS 14+ · free and open source (MIT)
Italiano · Threat model · Security
Blurry finds faces, covers them with a solid black box (or pixelation), and writes a new file with no metadata: no GPS position, no camera model, no dates, no hidden thumbnail of the original. It runs entirely offline. It has no server, no account, no telemetry and no update check, and it refuses to open network connections even if something tries.
Always check the result before you share it: the detector can miss faces, and Blurry does not hide bodies, voices or places. See What it does not do.
Install
Mac
Apple Silicon (M1 or later), macOS 14 or later.
- Download
Blurry.dmgfrom the Releases page. - Open it and drag Blurry onto the Applications folder.
- The first time, macOS warns that it cannot verify the developer: Blurry is not signed by Apple. Open System Settings › Privacy & Security, scroll down and click Open Anyway next to Blurry. You only do this once.
Windows and Linux
The new formats are a per-user Windows 11 x64 installer and an archive with a per-user installer for Ubuntu 24.04 x86-64. They bundle Python, Qt, the model and processing dependencies. Native packages are built and tested in CI and available as artifacts in the checks of PR #2, ahead of publication on Releases. Interactive testing on real desktop systems remains outstanding. See distribution and verification status for system libraries, installation, uninstall and the exact tests still outstanding.
With Python (engine, servers, containers, CLI and optional Qt)
You need Python 3.12. The simplest way is pipx (or uv tool). With the
desktop app:
pipx install "blurry-opsec[gui]"
Command line only:
pipx install blurry-opsec
The app
On a Mac (Blurry.dmg):
- Drop photos and videos on the window, or use Choose Files… (⌘O).
- A guide takes one file at a time: the file in the middle, and below it one choice at a time (sensitivity, cover, margin, and the sound for videos). From the cover step on, the picture shows exactly what will be exported; on a video you can play the covered result.
- Correct the boxes by hand if needed: draw, move, resize or remove boxes on photos; in videos switch off a track that is not a face, or draw a still box over a span of time.
- Export… opens the save panel on the original's folder, with
<name>_blurry. The original is never touched. If no face was found, Blurry asks first.
Every file of the session is in View › Queue (⌘L). On first launch, an introduction explains how to work and the detector's limits; contextual tips then accompany the first file. Replay it from Help › Show the Guide Again or from Settings.
Blurry › Settings… (⌘,) opens sensitivity, cover and margin, with an option to restore recommended values. Changes also apply to the open file. This window also contains the guide, the installed version, Releases for manual updates and uninstallation.
On Windows and Linux, open Blurry from your applications menu after installing;
with the Python package, run blurry with no arguments (or blurry-app):
- Drop photos and videos on the window, or use Choose files…. Each file is analysed in a separate process; nothing leaves your computer.
- Review any file. Boxes found by the detector are yellow, boxes you add are teal. Drag on an empty area to add a box, drag a box to move it, drag its corners to resize it, press Delete to remove it. Preview result shows exactly what will be exported. In videos, scrub the timeline (uncertain moments are marked in red), turn off a track that is not a face, or draw a box that covers an area for a span of time.
- Export. If a file has no face and you added none, Blurry asks before exporting it.
Both apps remember only a few settings (sensitivity, cover, margin, language, and whether the guide was seen): never file names, folders or recent files. The Qt app uses its own file picker, because Qt's dialogs keep a list of recent folders; the Mac app uses the system's panels and removes what they record as soon as they close.
What it does
- Covers faces in photos and videos, using the YuNet face detector (bundled; its SHA-256 is checked on every start, and Blurry refuses to run if it does not match).
- Removes all metadata:
- photos: EXIF (including the embedded thumbnail), GPS, XMP, IPTC, colour profiles and comments;
- videos: container and track tags (QuickTime location, device, dates), chapters, subtitles, data tracks (such as GoPro and drone GPS) and cover art.
- Applies the rotation of phone photos and videos to the pixels first, so sideways faces are not missed, and the output looks the same as before without carrying rotation metadata.
- Drops audio by default, because voices can identify people. Keep it with
--keep-audio. - Never overwrites anything: the original stays untouched, and if the output name is taken a numbered name is used.
- Never stays silent when no face is found: it warns, and with
--strictit writes nothing and exits with code 2.
What it does not do
Read the threat model before relying on Blurry. In short, it does not hide bodies, clothes, tattoos, voices, places, reflections, or the camera sensor's fingerprint; it cannot cover a face the detector does not find; it does not delete your original, which may also be synced to iCloud or Google Photos.
The detector can miss faces, especially faces in profile, in the dark, very small, or turned
sideways. Always look at the result before sharing it. Files with uncertain detections are listed
under flags in the --json report.
Uninstall
Mac: open Blurry › Settings… › Uninstall and click Uninstall Blurry…. After confirmation, the app moves to the Trash and its preferences are removed. Photos, videos and exports stay where they are. Reinstalling the app starts onboarding from scratch.
You can also quit Blurry and drag it from Applications to the Trash. In that case preferences
remain: to reset them, run defaults delete com.chronocol.blurry in Terminal with the app closed.
Windows and Linux: Settings → Uninstall. Windows also supports removal from
system Apps; Linux provides ~/.local/opt/blurry/uninstall.sh with the app closed.
Complete removal clears preferences and restarts onboarding after reinstallation.
See distribution.
With Python: pipx uninstall blurry-opsec; use Qt Settings → Uninstall → Clear
preferences and close first if you also want to reset its preferences.
Report a problem
Something does not work, or a face is not covered? Open an issue: say what you did and what happened, without attaching photos or videos of real people. Security vulnerabilities do not go in public issues: follow SECURITY.md.
The Qt app offers first-run onboarding, replayable from Guide and Settings.
Settings includes editable defaults, manual updates in the external browser and
uninstall. CLI invocations with arguments remain headless even with [gui] installed.
From the command line
blurry photo.jpg
writes photo.blurry.jpg next to the original.
blurry IMG_0001.HEIC clip.mov -o ~/Desktop/clean
writes IMG_0001.blurry.jpg and clip.blurry.mp4 in ~/Desktop/clean.
blurry INPUT... [-o FOLDER] [--level base|medium|high] [--mode solid|pixel]
[--padding 0.25] [--keep-audio] [--no-faces] [--watermark TEXT]
[--strict] [--json] [--debug]
| Option | Meaning | Default |
|---|---|---|
-o FOLDER |
Where to write the outputs | next to each original |
--level |
Detection sensitivity: base (clear frontal faces only), medium, high (also small or partly hidden faces) |
high |
--mode |
solid black box or pixel (pixelation) |
solid |
--padding |
Margin around each face, as a fraction of its long side, on every side | 0.25 |
--keep-audio |
Keep the audio track (re-encoded to AAC) | audio removed |
--no-faces |
Only remove metadata, cover nothing | |
--watermark TEXT |
Add a text watermark | off |
--strict |
If a file has no faces, write nothing for it and exit with code 2 | |
--json |
Print one JSON report per file on stdout | |
--debug |
Debug output on stderr | off |
Accepted files. Photos: JPEG, PNG, WebP (still), HEIC/HEIF. Videos: MP4, MOV, M4V, MKV, WebM, AVI. GIFs and animated images are refused. Photos come out as JPEG (PNG stays PNG); videos come out as MP4 (H.264).
Exit codes. 0 all good · 1 an error · 2 no face found with --strict.
Progress is printed on stderr as __PROGRESS__ {json} lines, for scripts and integrations.
The CLI contract documents JSON Lines, progress and exit codes for backend processes and pipelines, including global errors and strict batches. The Node process adapter example does not modify Chrono.
Verify what you download
Every release on GitHub comes with a SHA256SUMS file, a CycloneDX SBOM, and a GitHub
build-provenance attestation for each file, which proves it was built by this repository's
release workflow.
-
macOS / Linux, in the folder with the downloads:
shasum -a 256 -c SHA256SUMS
-
Windows (compare the result with the line in
SHA256SUMS):CertUtil -hashfile <file> SHA256 -
Provenance, with the GitHub CLI:
gh attestation verify <file> --repo Chrono-Web/BLURRY
The PyPI package is published from the same workflow with Trusted Publishing (no tokens), and PyPI shows its provenance on the project page.
Known limits
- Faces in profile, in the dark, very small or turned sideways can be missed (see above).
- HDR videos from phones (10-bit HEVC) come out as 8-bit SDR H.264: colours can look flatter.
- On macOS, processing a video prints a harmless
objc ... implemented in bothwarning, because OpenCV and PyAV each bundle their own FFmpeg.
Licence
Blurry is MIT-licensed. The PyPI package contains only Blurry's code, the YuNet model (MIT) and the Geist font (OFL). Desktop installers also bundle dependencies and FFmpeg with x264 and x265, which are GPL-2.0-or-later, and the PyInstaller bootloader (GPL-2.0 with an exception for the programs it runs): see THIRD_PARTY_LICENSES.md for every licence and the exact sources.
Metadata
Release files for blurry-opsec 0.1.2b1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| blurry_opsec-0.1.2b1.tar.gz | 507.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| blurry_opsec-0.1.2b1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 915.7 kB
Release files / blurry_opsec-0.1.2b1.tar.gz
| Download URL | blurry_opsec-0.1.2b1.tar.gz |
|---|---|
| Size | 507.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
376544b4145dd57c35beba5115bb552fbbcc2acd81f113c34493f072f0674169
|
|
BLAKE2b-256 checksum How to use checksums |
81edc18486b45ca21c59d6886ff483093c8977d6df536c5c3b3e4478ad04f2f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency logRelease files / blurry_opsec-0.1.2b1-py3-none-any.whl
| Download URL | blurry_opsec-0.1.2b1-py3-none-any.whl |
|---|---|
| Size | 408.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2d5f72a4819bb7ddf78008f4e7ab5111be8e1b836fc9c417c3fd6c64e908beef
|
|
BLAKE2b-256 checksum How to use checksums |
a27119ee1d01fbd61517e64f833ddcf0ec6cd3e0b5e4be3cf7702b8a40fadc1d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency log