Add authentic camera and film characteristics to digital renders and synthetic media.
AuthentiGen is a self-hostable web app that runs images through a deterministic, pixel-level optical pipeline — sensor grain, lens optics, chromatic aberration, color grading, JPEG artefacts, and camera EXIF — so optically clean digital output picks up the physical characteristics of a real photographic capture.
Quick start · How it works · Architecture · Contributing · Intended use
A deterministic photographic and cinematic realism pipeline, wrapped in a full-stack TypeScript web app that is complete and runnable on your own machine.
CG renders, 3D output, and generative imagery share a problem: they are optically too clean. A real camera imposes a physical signal chain — a lens that distorts and disperses light, a sensor that adds shot noise and hot pixels, a color path that drifts, and a codec that quantises. AuthentiGen models that chain and applies it as a post-process, the same way a compositor adds grain and lens artefacts to a CG plate before it will cut against live-action footage.
- Real processing, not AI generation. The core (
server/humanizer.ts) is a ~1000-line deterministic pipeline built onsharpand raw buffer math. No model, no inference — the same input at the same intensity always produces the same output, which is what makes it usable inside a reproducible render or dataset pipeline. - Images. Each upload is processed in one pass through the deterministic pixel pipeline (JPG / PNG / WEBP, up to 20 MB).
- Three intensity levels — Light / Medium / Heavy — mapped to plausible camera profiles (e.g. ISO 200 phone → ISO 3200 35mm film).
- Free and unlimited. Self-hosted with no credits, paywalls, or usage limits — run it on your own server and process as much as you like.
- Everything around it is built: email/password auth, batch uploads, a job dashboard with live progress, and an admin panel.
| Area | What's included |
|---|---|
| Realism | 13-step deterministic optical pipeline, Light/Medium/Heavy intensity |
| Auth | Email + password, bcrypt hashing, JWT session cookie (1-year) |
| Jobs | Async processing, progress polling, batch upload (1–10 files) with ZIP download |
| UI | React 19 + Tailwind v4 dark theme, before/after comparison slider, dashboard, admin |
| Quality | Strict TypeScript (0 errors), passing Vitest tests (server + client), Prettier |
- Client: React 19, Vite 7, TypeScript, Tailwind CSS v4, tRPC + React Query, Wouter, Framer Motion, three.js, shadcn/ui (Radix)
- Server: Node + Express, tRPC, Drizzle ORM, MySQL 8,
sharp,jose(JWT),bcryptjs - Tooling: pnpm, esbuild, Vitest, Prettier
Requires Docker + Docker Compose. This spins up MySQL and the app together, runs migrations, and serves the app.
git clone <your-fork-url> authentigen
cd authentigen
cp .env.example .env # defaults work as-is for local Docker
docker compose up --buildThen open the URL printed in the logs (default http://localhost:3000). Sign up and upload an image.
Requires Node 20+, pnpm, and a running MySQL 8 instance.
git clone <your-fork-url> authentigen
cd authentigen
pnpm install
cp .env.example .env # then edit DATABASE_URL to point at your MySQL
pnpm db:push # create tables
pnpm dev # starts on http://localhost:3000 (auto-picks next free port)pnpm build # client → dist/public, server → dist/index.js
pnpm start # NODE_ENV=productionCopy .env.example to .env. Summary:
| Variable | Required | Notes |
|---|---|---|
DATABASE_URL |
✅ | MySQL connection string. Docker Compose supplies this automatically. |
JWT_SECRET |
✅ (prod) | 32+ char random string for signing sessions. Auto-generated and written to .env on first dev run. |
APP_BASE_URL |
optional | Public origin used in links (e.g. job-completion emails). |
STORAGE_BACKEND |
optional | local (default) or s3. See Storage backends. |
S3_BUCKET / S3_REGION / AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY |
for S3 | Required when STORAGE_BACKEND=s3. S3_ENDPOINT + S3_FORCE_PATH_STYLE enable R2/MinIO/B2; S3_PUBLIC_URL serves long-lived URLs via a CDN. |
SMTP_HOST / SMTP_FROM / SMTP_* |
optional | Enable email; blank disables it (logs to console). See Email. OWNER_EMAIL receives admin notifications. |
RATE_LIMIT_WINDOW_MS / RATE_LIMIT_MAX |
optional | API rate limit (default 100 req / 60s). Set TRUST_PROXY behind a proxy. |
MAX_CONCURRENT_IMAGE_JOBS |
optional | Cap on simultaneous image processing jobs (default 4). |
By default, uploads and processed output are stored on the local filesystem under storage/ and served
via the /storage route. To use object storage, set STORAGE_BACKEND=s3 plus S3_BUCKET, S3_REGION,
and AWS credentials. It works with any S3-compatible service — set S3_ENDPOINT (and
S3_FORCE_PATH_STYLE=true for MinIO) for Cloudflare R2, MinIO, or Backblaze B2. Set S3_PUBLIC_URL to a
public/CDN base for long-lived links; otherwise the app issues presigned URLs (max 7-day expiry). The
Compose dev profile includes a MinIO service for local testing — see below.
Email is optional and off unless configured — notifyOwner and job-completion notices fall back to
console logging. Set SMTP_HOST, SMTP_FROM (and SMTP_USER/SMTP_PASSWORD if your provider needs
auth) for any SMTP provider. For local testing, docker compose --profile dev up starts
Mailhog — point SMTP_HOST=mailhog, SMTP_PORT=1025.
A request flows: upload → tRPC jobs.create → async processor → local storage → client polls jobs.status → before/after view → download.
The image pipeline applies, in order: barrel distortion → Sobel edge + skin-tone masking → edge-aware chromatic aberration → shadow crush / highlight clip / micro-banding → ring motion blur → sensor hot pixels → color-temperature drift → focus-falloff blur → film grain + lens dust + vignette → mozjpeg re-encode with camera EXIF. Dark/neon scenes additionally get haze, neon bloom, and rain streaks.
Every stage is closed-form pixel math driven by the input and the intensity setting alone, so a run is fully reproducible — an important property when the output feeds a versioned render pipeline or a training set.
Processing is free and unlimited — there are no credits or per-job costs.
Full details — data model, job lifecycle, and pipeline internals — are in ARCHITECTURE.md.
pnpm check # TypeScript (no emit)
pnpm test # Vitest — server (node) + client (jsdom) projects
pnpm format # Prettier writeclient/ React + Vite front end (pages, components, hooks)
server/ Express + tRPC API, realism pipeline, auth, storage
_core/ Server bootstrap, env, auth, context, vite/static serving
shared/ Constants/types shared between client and server
drizzle/ Drizzle schema + migrations (MySQL)
storage/ Local file storage for uploads and processed output (gitignored)
AuthentiGen adds authentic photographic and cinematic characteristics to digital imagery. It was built for three concrete jobs.
CG renders and composited elements are optically perfect in a way real footage never is, and that is precisely why they refuse to sit in a live-action plate. Re-imposing the camera's signal chain — barrel distortion, chromatic aberration at high-contrast edges, sensor grain that scales with ISO, lens vignetting, halation blooming off highlights — is routine compositing work. AuthentiGen packages that pass as a deterministic, batchable step you can point at an entire render output directory.
The Light and Medium profiles stand on their own as a film-emulation grade: color-temperature drift and warmth, gentle shadow crush with highlight roll-off, film grain, and a soft vignette — applied uniformly across a shoot or a product set, with identical parameters every time. Because the pipeline is deterministic, a look is reproducible across a whole campaign rather than hand-tuned per asset.
Vision models trained on clean or synthetic imagery degrade when they meet real camera output, because real lenses and sensors introduce aberration, noise, and compression that the training set never contained. Domain randomization and sensor-realistic augmentation are a well-established answer to this: widen the training distribution to cover the optical variation a deployed camera actually produces, and the model generalises better on real data.
AuthentiGen generates exactly that variation. It emits physically-motivated camera artefacts — wavelength-dependent lens dispersion, ISO-scaled shot noise, DCT quantisation error, focus falloff — rather than the generic blur-and-jitter of most augmentation libraries, and it does so with no learned component anywhere in the chain. An augmented set can therefore be regenerated exactly from the originals plus an intensity setting, which keeps the augmentation stage versionable and auditable alongside the rest of the training code.
Please use AuthentiGen responsibly and legally. It is not intended for fraud, disinformation, academic dishonesty, defeating content-provenance or watermarking systems where that is deceptive or unlawful, or misrepresenting synthetic media as authentic in contexts where authenticity matters. You are responsible for complying with the laws and platform policies that apply to you.
Done recently: pluggable S3 storage, SMTP email, API rate limiting, crash-recovery for jobs, and a front-end test project. Still open (contributions welcome — see CONTRIBUTING.md):
- A distributed job queue (e.g. Redis/BullMQ) for multi-instance deployments
- On-read presigned URLs so S3 links never expire without a CDN
- Broader front-end and integration test coverage
- Email verification on signup
See SECURITY.md for reporting vulnerabilities and current hardening limitations.
MIT © 2026 Yousef Ferwana