Case study
Glow — Local AI Portrait Retouching
A desktop and mobile retouching app that runs 14 neural networks entirely on the user’s own device — skin, shine, tone, teeth, eyes and backdrop — with batch export, RAW import and a Photoshop panel.

Overview
Project overview
Glow is a photo-retouching application that keeps the entire pipeline on the user’s own machine. Fourteen neural networks — skin masks, face parsing, three skin passes, shine, tone, teeth, eyes and backdrop cleanup — run in-process through ONNX Runtime and ncnn, GPU-accelerated on every platform with a CPU fallback. Photographs are never uploaded: the app streams verified model weights once, then works offline. One Rust engine drives Windows, macOS, Linux, Android and a Photoshop panel.
ROLE
End-to-end product engineering: native retouch engine (Rust), desktop + mobile app (Tauri 2 / React), model delivery, licensing, Photoshop integration
TIMELINE
2026
FOCUS
- On-device inference — no photograph leaves the machine
- One engine across desktop, mobile and Photoshop
- Verified, resumable model delivery (SHA-256 per file)
- Retoucher-grade controls instead of one magic button
- Batch export at full resolution, with RAW import
Story
Problem → Solution → Outcome
PROBLEM
Portrait retouching is skilled, repetitive work: one shoot is hundreds of frames of skin, shine, stray hairs and a dusty backdrop. Cloud retouching services solve the labour but ask photographers to upload their clients' faces to somebody else’s servers — which plenty of contracts, and plenty of clients, simply do not allow.
SOLUTION
Glow puts the whole pipeline on the photographer’s own machine. A Rust engine runs fourteen models over the frame in a single pass and keeps each stage as its own layer, so the sliders re-mix a cached result instead of re-running the networks. Weights are streamed once from a signed manifest and verified file by file. The same engine backs the Android build through an INT8 ONNX path and the Photoshop panel through a loopback bridge, and the licence is an offline-verifiable signed entitlement rather than a call home.
OUTCOME
Photographers get studio-grade retouching with per-stage control, batch export at full resolution and RAW import — without a single frame leaving the device. The business gets one engine to maintain across five surfaces instead of five.
Highlights
What we built
Key systems shipped end-to-end — designed for reliability, conversion, and scale.
A retoucher’s panel, not one magic button
Every stage is its own strength, so the operator decides how far each effect goes — the way retouching actually works.
- Minimal / Natural / Fashion skin styles
- Refine split into General and Texture, weighted separately for face and body
- Eyes split into clarity, brilliance and vessels — per eye, per face
Everything stays on the device
No frame is uploaded anywhere. The app fetches its model weights once, verifies them, and then retouches offline.
- No account needed to process a photograph
- The licence is an Ed25519-signed entitlement checked locally
- Works on location, on a plane, behind a firewall
One engine, five surfaces
The same Rust core runs behind the desktop UI, the Android build and the Photoshop panel — so a fix lands everywhere at once.
- Preview and export are built from the same cached layers
- The Photoshop panel reuses the engine over a loopback bridge
Batch export at full resolution
A whole shoot goes through the queue with per-photo progress, naming rules and an export quality that is independent of the preview.
- Grid and single view, sorting, filters and marks
- Four quality presets that remove passes, not resolution
Manual tools that survive the sliders
Selection, patch and background blur are replayed on top of the retouch result, so moving a slider afterwards does not throw the manual work away.
- Patch is Poisson seamless cloning, computed on the crop for speed
- Background blur reuses the segmentation model already in memory
Model delivery you can verify
Weights live neither in the repository nor in the installer. They are streamed from a manifest and checked file by file before anything is switched on.
- 132 MB desktop pack, 243 MB mobile pack
- Resumable over HTTP Range — a dropped connection continues
- A failed digest never activates the pack
Pipeline
How it works
What happens to a frame, step by step.
- 01DecodeJPEG · PNG · TIFF · WebP · RAW
Orientation, ICC and RAW development, in pure Rust.
- 02Face analysis0001 · 0008 · 0002 · 0013
Skin mask, face boxes with five landmarks, eight-class face parsing, part detector — every face in the frame.
- 03Refine0003 · 0004 · 0005
Low-frequency, main and small-multiscale passes — face and body weighted separately.
- 04Shine0011
Detects specular skin and drops it back without flattening the highlight.
- 05Tone0006
Global skin-tone balance, guarded against non-finite output.
- 06Teeth & eyes0009 · 0010
Whitening, plus clarity, brilliance and vessel removal mixed independently — per eye, per face.
- 07Clean backdrop0014 · 0015 · 0016
Segments the studio backdrop, then removes creases, dust and stains — and exits early when there is no backdrop.
- 08Compose & encode—
Each stage is a cached layer, so a slider re-mixes the result instead of re-running the models.
Challenges
Technical challenges
The hard parts — and the solutions that made the system stable.
Results
Impact
Measured outcomes and operational wins.
A full retouch pass runs on the operator’s own hardware — a median of about ten seconds per pass on a 2026 tablet, faster on a GPU desktop.
Android output matches the desktop file to 53.8 dB — the mobile build is a port, not a downgrade.
4.4× faster mobile inference after the INT8 move, and another 18.8 % off batch time from removing duplicated work.
One codebase covers Windows, macOS, Linux and Android, plus a Photoshop panel that reuses the same engine.
Model packs are verified per file, so a broken or truncated download can never be activated.
Availability
Where it runs
One codebase, every surface it ships on.
Windows
Signed NSIS installer, DirectML acceleration, in-app updates.
macOS
11.0+, Metal acceleration, same engine as the preview.
Linux
AppImage and .deb from signed CI builds, CUDA acceleration.
Android
INT8 ONNX inference with a GPU delegate, Play billing, export to the gallery.
Photoshop
UXP panel that hands the flattened document to the running app over 127.0.0.1 and places the result as a new layer.
Stack
Tech stack used
Tools and patterns used on this build.
Retouch engine
- Rust (in-process, no sidecar)
- ndarray + hand-written resamplers (area / cubic / lanczos4)
- Tiled inference with residual restore
- Poisson seamless cloning
Inference runtimes
- ONNX Runtime — DirectML / CUDA / CoreML
- ncnn + Vulkan (desktop)
- INT8 QDQ quantisation via ORT (Android)
- TFLite GPU delegate (Android)
- CPU fallback on every platform
Models
- SegFormer-B0 ×3 (skin, face parts, backdrop)
- YOLOv8n ×2 (faces + 5 landmarks, face parts)
- RRDB + two ResNet skin passes
- Tone, teeth, eye and backdrop cleanup nets
Application
- Tauri 2 + Rust commands
- React 19 + TypeScript + Vite
- WebGL layer compositor
- Custom window chrome, 3 languages, dark/light
Delivery & licensing
- Manifest-driven model pack, HTTP Range resume
- SHA-256 per file + atomic activation
- Ed25519 offline entitlement
- Signed auto-update (minisign), Play Billing
Integrations
- Photoshop UXP panel over loopback HTTP
- RAW decode (rawloader + imagepipe)
- ICC handling
- Device + GPU telemetry (NVML, PDH, DXGI)
Metrics
Impact metrics
Neural networks in one pass
14models, all on-device
Photographs uploaded
0bytes leave the device
Mobile inference
4.4× faster after the INT8 port
Next
Next case study
Keep browsing the system.
Rentai Glass — real-estate listing verification by photo
Upload a photo or paste a listing link — we find duplicates and near-matches to reduce fraud risk.