Ctrl + Shift + A to toggle
Tag thousands of photos with a vision model running on your own machine. Develop them in a Lightroom-style editor. No cloud uploads. No model lock-in.
You have a folder of photos with no descriptions, no keywords, and no plan. Send them to a cloud service — pay per image, hand your client's photos to a third party, hope the tags are usable. Tag them by hand — burn a week on something a computer should do in an afternoon. Use an existing tool — most are thin wrappers over OpenAI or workflow-heavy Lightroom plugins that don't understand the image. Graffiti runs entirely on the user's computer. Point it at a folder, pick a vision model, walk away. Every JPEG, PNG, TIFF, HEIC, WebP, and 24 RAW formats come back tagged with a description and 12–20 keywords burned into standard XMP / IPTC metadata. Bridge sees it. Lightroom sees it. NeoFinder sees it. The client sees a properly catalogued archive.
Walks a folder, runs every supported image through a local vision-language model, and writes natural-language captions + 12–20 keywords into standard XMP / IPTC fields.
Exposure, tone curve, split toning, vignette, grain, crop, AI background removal, 2×/4× upscale, LaMa generative fill. Every slider writes to Adobe Camera Raw's crs:* XMP namespace.
Preview folders before importing — no DB writes, fast thumbnail grid, metadata-aware filter chips, rate / pick / reject keyboard shortcuts.
Opt-in InsightFace buffalo_l + sqlite-vec kNN — drop a reference photo, find every other photo of that person across workspaces. EULA-gated.
Browse, pull, and benchmark vision models from inside the app. Knows which models fit your VRAM and which licenses require explicit acceptance.
CSV, JSON, Lightroom XMP sidecars, NeoFinder XML, Markdown manifests, hierarchical Keywords.txt — plus AES-256-GCM encrypted .gvdb archives for Studio.
PySide6 (Qt 6) + QML / QtQuick — the same toolkit Krita, FreeCAD, and OBS use. GPU-accelerated rendering, ~60 fps grid even with 100k assets. The main thread runs Qt + QML and never blocks. qasync bridges asyncio onto Qt's event loop for HTTP and LLM I/O. CPU-bound work — thumbnails, hashing, metadata writes, face inference, image rendering — runs on QThreadPool or anyio.to_thread.run_sync.
Ollama and LM Studio are first-class. The bundled installer ships the Ollama CLI. The in-app Model Hub fetches, benchmarks, and gates Qwen 2.5-VL, Llama 3.2 Vision, Gemma 3, MiniCPM-V, LLaVA, Moondream, and Pixtral — the hub knows which models fit your VRAM and which require explicit license acceptance. No client photos ever leave the machine unless the user opts into a cloud provider on Pro.
Captions write to dc:description. Keywords write to dc:subject (one per tag) and the IPTC-IIM legacy mirror. Face tags write to Iptc4xmpExt:PersonInImage. Every develop adjustment writes to Adobe Camera Raw's crs:* XMP namespace — exposure, tone curve, split toning, vignette, grain. Adobe Bridge sees it. Lightroom Classic sees it. NeoFinder sees it. exiftool is the primary writer (subprocess), pyexiv2 the fast path.
5 priority lanes (URGENT / HIGH / NORMAL / LOW / BACKGROUND), RAM- and VRAM-aware backpressure that pauses at 90% memory and resumes at 75%, persistent across crashes via SQLite WAL, cooperative cancellation so you can drop a batch mid-flight without losing the rest, sanity validator that auto-retries with a configured fallback model when the primary returns garbage, watch folders that wait for files to settle before triggering, scheduled batches with cron-style triggers.
Every model download routes through an explicit per-model license-acceptance dialog. The SHA-256 hash of the license text is persisted per (model_id, license_string), so the dialog only re-fires when the upstream license actually changes. Graffiti does not redistribute model weights — downloads route directly from Ollama / HuggingFace / GitHub Releases to the user's disk. Graffiti is a fetcher, not a mirror.
Hardware-bound; full feature set on for the trial window.
Local providers (Ollama / LM Studio / LocalAI / OpenAI-compat), full edit module, 2 machines.
Adds cloud providers (OpenAI / Anthropic / Gemini), watch folders, batch presets, reviewer sign-off, 3 machines.
Floating licenses, audit log, shared prompt library, encrypted .gvdb export, priority support.