Skip to content

About

A free, privacy-focused browser tool that adds physically-ordered camera imperfections and real JPEG artifacts to images. 14 effects, per-effect regions, presets — 100% local processing, no uploads.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

69 Commits

Folders and files

Repository files navigation

DesImageEditor

Live demo License: MIT No build step Tests Privacy

A free, privacy-focused web tool that adds real-world camera imperfections and compression artifacts to images — the grain, flare, softness, and JPEG blocking that tell your eye "this was taken by a real camera." All processing happens locally in your browser: no uploads, no server, no paywall.

Replicates and extends the JPEG artifact functionality of onlinejpgtools.com/add-jpg-artifacts with 14 physically-ordered effects across five stages of a camera's imaging pipeline.

Try it live →

What This Is

  • 14 camera-imperfection effects in one pass (js/effects/) — lens flaws, focus flaws, sensor noise, phone-ISP color grading, and real JPEG compression, applied in physically-correct order (light enters the lens, passes through focus, hits the sensor, gets processed, gets compressed).
  • Real JPEG artifacts, not simulated ones (js/effects/jpeg-artifacts.js) — the browser's native JPEG encoder (Chrome's libjpeg-turbo, Firefox's mozjpeg) produces genuine compression blocking, ringing, and color banding through an encode → decode → re-encode cycle.
  • Per-effect regions (js/ui/region.js) — drag, resize, and position a colored overlay per effect, so grain can cover one area while motion blur hits another. Numeric X/Y/W/H inputs for precise placement.
  • One-click presets (js/effects/presets.js) — five camera recipes from "Smartphone Snapshot" to "AI Realism (Colour Corrected)", plus a session-persistent Custom preset that captures your current settings automatically.
  • Zero dependencies, zero build step — plain ES modules served statically; index.html + css/ + js/ is the whole app. Verified: no fetch, no XMLHttpRequest anywhere in the app code — images never leave the browser.
  • 16 automated effect test suites (tests/) — each effect's physics has a standalone test file (radial darkening, signal-dependent grain, blur attenuation compensation, region scaling, …).

How It Works

       1. LOAD                      2. LENS                  3. FOCUS              4. SENSOR                  5. COLOR / ISP                    6. COMPRESS
+--------------------------+    +------------------------+    +-------------+    +----------------------+    +------------------------+    +-----------------------------+
| any image + any static   |    | vignetting, edge       |    | soft focus, |    | ISO grain, chroma    |    | white balance drift,   |    | real encode -> decode ->    |
| server (server.py :8000, |    | softness, chromatic    |    | motion blur |    | noise, dead pixels,  |    | dynamic range stretch, |    | re-encode cycle through the |
| npx serve .) - runs      |    | aberration, lens flare |    | (per-effect |    | dust spots           |    | split toning           |    | browser's native JPEG       |
| 100% in your browser,    |  > | (full-frame effects)   |  > | regions)    |  > | (per-effect regions) |  > | (full-frame effects)   |  > | encoder -> download         |
| no uploads               |    |                        |    |             |    |                      |    |                        |    |                             |
+--------------------------+    +------------------------+    +-------------+    +----------------------+    +------------------------+    +-----------------------------+
  1. Load. Open the page, drop in an image. Nothing is uploaded — the Canvas API reads the file locally.
  2. Lens. Full-frame optical flaws: radial vignetting, progressive edge softness (field curvature), chromatic aberration fringing, lens flare ghosting.
  3. Focus. Gaussian soft focus (missed autofocus) and directional motion blur, each on its own draggable region.
  4. Sensor. High-ISO luminance grain (signal-dependent), chroma noise blotches, stuck dead/hot pixels, sensor dust spots — all region-addressable.
  5. Color / ISP. The phone-processor look: white balance drift from mixed lighting, dynamic-range stretch (deep shadows, bright highlights), split toning (blue shadows, golden highlights).
  6. Compress. The enabled result is cycled through the browser's real JPEG encoder so the artifact at the end of the chain is genuine compression damage, then the image is ready to download.

js/effects/pipeline.js runs enabled effects in this registry order with intermediate caching, so re-applying after a small change only recomputes the stages downstream of what changed.

Effects

14 effects across five categories. Each effect has its own strength slider (0–100%) and can be toggled independently.

Lens Flaws (full frame)

Effect Description
Vignetting Radial darkening toward image edges and corners
Edge softness Progressive blur toward frame edges simulating field curvature / astigmatism
Chromatic aberration Color fringing on high-contrast edges from lens dispersion
Lens flare Ghost reflections and veiling haze when shooting toward bright light

Focus Flaws (per-effect region)

Effect Description
Soft focus Gaussian blur simulating missed smartphone autofocus
Motion blur Directional blur from camera shake or slow shutter speed

Sensor Flaws (per-effect region)

Effect Description
ISO grain High-ISO luminance noise, monochromatic and signal-dependent for realism
Chroma noise Blotchy color noise from aggressive high-ISO chroma denoise
Dead/hot pixels Stuck bright or dark pixels from sensor manufacturing defects
Dust spots Small dark spots from dust on the camera sensor

Color / ISP (full frame)

Effect Description
White balance drift Warm/cool color cast across the frame, as from mixed lighting
Dynamic range stretch Added contrast with deeper shadows and brighter highlights, phone-ISP tone mapping style
Split toning Blue-ish shadows and golden highlights — the signature phone-photo color grade

Compression (per-effect region)

Effect Description
JPEG artifacts Compression blocking, ringing, and color banding from heavy JPEG re-encoding

Pipeline Order

Applied in this physical order (js/effects/registry.js):

  1. Vignetting · 2. Edge softness · 3. Chromatic aberration · 4. Lens flare ·
  2. Soft focus · 6. Motion blur · 7. ISO grain · 8. Chroma noise · 9. Dead/hot pixels ·
  3. Dust spots · 11. White balance drift · 12. Dynamic range stretch ·
  4. Split toning · 14. JPEG artifacts

Per-Effect Regions

The 8 region-capable effects each get their own colored overlay on the input canvas:

  • Click the overlay to make it active (solid border) vs inactive (dashed border)
  • Drag to reposition, drag the bottom-right corner to resize
  • "Edit region" buttons on each effect card auto-select that effect's overlay
  • Numeric X, Y, Width, Height inputs reflect the active region
Effect Overlay color
Motion blur Red (#ff6b6b)
Soft focus Yellow (#ffd93d)
ISO grain Blue (#4d96ff)
Chroma noise Teal-green (#38d9a9)
Dead/hot pixels Orange (#ff922b)
Dust spots Purple (#cc5de8)
JPEG artifacts Teal (#20c997)

Full-frame effects (vignetting, edge softness, chromatic aberration, lens flare, and the color/ISP group) apply to the entire image and show a "Full frame" badge instead.

Presets

Preset Effects Use case
Smartphone Snapshot Soft focus 20%, ISO grain 25%, JPEG artifacts 40% Slightly imperfect everyday photo
Old/Cheap Lens Vignetting 55%, Chromatic aberration 50%, Edge softness 45% Worn-out budget optics
High ISO Night Shot ISO grain 80%, Motion blur 30%, Dead pixels 35% Noisy, slightly blurry low-light capture
Vintage Film Vignetting 40%, Dust spots 30%, ISO grain 20%, Chromatic aberration 35% Retro film aesthetic
AI Realism (Colour Corrected) Chroma noise 30%, ISO grain 20%, WB drift 20%, Dynamic range 25%, Split toning 30%, JPEG artifacts 25% Targets the AI-vs-real color tells; layer a lens/film preset on top if the shoot calls for it

After processing, your current configuration is automatically saved as a Custom preset for quick re-use during the session.

Getting Started

python3 server.py
# Open http://localhost:8000

server.py is a 15-line static file server that also sends cross-origin isolation headers. Any static server works:

npx serve .
python3 -m http.server 8000

Tests — each effect suite is a standalone Node script:

node tests/vignette.test.mjs          # one suite
for t in tests/*.test.mjs; do node "$t"; done   # all 16

Repository Layout

├── index.html                  # single-page app shell
├── server.py                   # static server (:8000) with cross-origin isolation headers
├── css/app.css                 # all styling
├── js/
│   ├── app.js                  # UI wiring, effect cards, region overlays, presets
│   ├── processor.js            # canvas processing + download
│   ├── utils.js
│   ├── effects/
│   │   ├── registry.js         # master list in pipeline order
│   │   ├── pipeline.js         # ordered runner with intermediate caching
│   │   ├── presets.js          # 5 camera recipes + session Custom
│   │   └── *.js                # 14 effect modules (one per effect)
│   └── ui/                     # upload, region selector, output panel
├── tests/                      # 16 standalone effect test suites (node, no framework)
└── docs/superpowers/           # design specs + implementation plans from development

Modeling Assumptions and Limitations

  • Effects are physically-inspired models, tuned by eye — vignetting, grain, and flare follow the right functional shapes (radial falloff, signal-dependent noise), but parameters are calibrated against human judgment, not measured against reference cameras.
  • JPEG artifacts are browser-dependent by design — they come from the browser's actual encoder, so Chrome and Firefox produce slightly different (both genuine) compression.
  • Non-deterministic effects re-roll — grain, noise, dust, and flare draw fresh randomness on every Apply, so two runs with identical settings differ, like two real frames from the same camera.
  • Processing is resolution-bound — everything runs on in-memory canvases at the source image's resolution; very large images take proportionally longer.

AI-Agentic Development

This app was engineered through an agentic AI workflow: 67 commits over four days (July 2026), driven by a loop of written design specs → implementation plans → agent implementation → systematic audit → targeted fixes. docs/superpowers/ preserves the actual specs and plans from that process (including the camera-flaws design and two audit-driven bugfix passes that fixed 14 rated bugs). The human role was direction and judgment: the effect physics wishlist, visual quality bar, and every accept/reject call.

Author

Built by D. Desmaan.

Licensed under the MIT License.

About

A free, privacy-focused browser tool that adds physically-ordered camera imperfections and real JPEG artifacts to images. 14 effects, per-effect regions, presets — 100% local processing, no uploads.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages