Skip to content

Add A10city Image Editor - WebAssembly-based browser image processor - #1

Merged
profradha merged 2 commits into
mainfrom
claude/wasm-image-editor-rust-3iy84l
Aug 25, 2026
Merged

Add A10city Image Editor - WebAssembly-based browser image processor#1
profradha merged 2 commits into
mainfrom
claude/wasm-image-editor-rust-3iy84l

Conversation

@profradha

Copy link
Copy Markdown
Member

Summary

This PR introduces the A10city Image Editor, a complete browser-based image processing application built with Rust/WebAssembly on the backend and TypeScript on the frontend. The editor allows users to convert, resize, crop, rotate, and adjust images entirely in the browser without uploading to any server.

Key Changes

Core Architecture

  • Rust/WASM Engine (crates/imagecore/): A WebAssembly image processing library that handles all pixel operations
    • Codec layer supporting 11+ input formats (PNG, JPEG, WebP, GIF, TIFF, BMP, ICO, TGA, QOI, PNM, HDR, Farbfeld) and 11 output formats
    • Pipeline-based architecture that replays edits from the pristine source each time, avoiding stacked resampling errors
    • Pixel operators for resampling (7 kernels from Nearest to Lanczos-3), affine geometry (rotation, flips), and tonal adjustments
    • Comprehensive test suite (pipeline.rs) validating all edit operations

Frontend Application

  • Main UI (src/main.ts): 1000+ lines orchestrating the editor state machine

    • Declarative pipeline system where UI controls mutate the edit pipeline and request redraws
    • Worker thread communication for non-blocking image processing
    • Real-time preview with busy state management
    • Crop overlay with interactive selection, rule-of-thirds guides, and keyboard support
  • Styling (src/editor.css, src/style.css): Comprehensive component and brand-kit styles

    • Responsive layout with sticky preview and scrollable controls
    • Interactive crop overlay with visual feedback
    • Accessible form controls and status indicators
    • WCAG 2.1 AA/AAA compliant color contrasts
  • Worker Thread (src/worker.ts): Offloads expensive operations to prevent UI jank

    • Manages Editor lifecycle and request correlation
    • Implements preview scheduler to coalesce rapid requests
    • Handles fallback to browser decoders for AVIF/HEIC/SVG
  • Type System (src/types.ts): Shared wire format between UI and WASM

    • Mirrors Rust serde structures for seamless serialization
    • Defines Pipeline, CropRect, ResizeSpec, AdjustSpec, and worker message types
  • Crop Overlay (src/crop.ts): Interactive crop selection component

    • Stores selection in crop-space pixels (source after flips/rotation)
    • Paints as percentages of canvas for resolution-independent behavior
    • Supports drag modes (move, resize from 8 edges), keyboard nudging, and aspect ratio locking

HTML & Assets

  • Index (index.html): Semantic HTML5 structure with accessibility features

    • Skip link, ARIA labels, and semantic landmarks
    • Responsive layout with mobile-first design
    • Open Graph and Twitter meta tags for social sharing
    • Google Fonts integration (DM Sans, JetBrains Mono, Space Grotesk)
  • Brand Assets (img/): Logo and favicon files for A10city branding

Build & Deployment

  • Vite Configuration (vite.config.ts): Optimized build setup with wasm-pack integration
  • TypeScript Config (tsconfig.json): ES2022 target with DOM and WebWorker support
  • Cargo Workspace (Cargo.toml): Rust workspace with optimized release profile (LTO, single codegen unit)
  • CI/CD (.github/workflows/):
    • ci.yml: Runs Rust tests and linting on pull requests
    • deploy.yml: Builds and deploys to GitHub Pages on main branch push
  • Package Config (package.json): Node.js dependencies and build scripts

Notable Implementation Details

  • No Server Upload: All processing happens in the browser; images never leave the user's tab
  • Pristine Source Replay: The pipeline is always replayed from the original decoded image, preventing quality degradation from stacked operations

https://claude.ai/code/session_0136PgRWHesdPLprcMp5CDk8

profradha and others added 2 commits August 25, 2026 13:49
Convert, resize, crop, straighten and adjust images entirely in the
browser. Nothing is uploaded: files are decoded, edited and re-encoded
inside a Web Worker in the tab.

Engine (crates/imagecore, Rust -> wasm32-unknown-unknown):
- codec: read PNG/JPEG/WebP/GIF/TIFF/BMP/ICO/TGA/QOI/PNM/HDR/Farbfeld,
  write all but HDR. EXIF orientation applied on open; formats without
  an alpha channel are flattened onto a caller-chosen matte.
- ops: SIMD resampling via fast_image_resize across seven kernels,
  affine warp and separable Gaussian via imageproc, tonal operators.
- pipeline: edits are declarative and replayed from the pristine source,
  so there is exactly one resample between the original pixels and the
  result. Crop is measured after rotation, in the frame the user sees.
  Exact multiples of 90 degrees fold into the lossless quarter-turn path.

OpenCV was evaluated and is not usable on this target: the opencv crate
binds a native build through libclang and does not support
wasm32-unknown-unknown, and reaching a browser at all would mean
Emscripten and opencv.js, which does not interoperate with wasm-bindgen.
imageproc provides the equivalent warpAffine and GaussianBlur routines in
pure Rust. Reasoning and limits are documented in the README.

Performance on a 6000x4000 source: straighten previews 391ms -> 81ms, via
shedding resolution before the warp, caching that reduction on a halving
ladder so a drag keeps hitting it, and bilinear preview warps against
bicubic exports. GIF export 2842ms -> 331ms by mapping the quality slider
onto the quantiser's effort dial. Previews coalesce, so a slider drag
costs one render per frame the engine can deliver.

Web app mirrors the A10city brand kit from a10citylabs/verify: navy and
lime palette, DM Sans / Space Grotesk / JetBrains Mono, shared navbar and
footer. Interactive crop overlay with ratio presets and keyboard nudging,
hold-to-compare against the original, and a format list built from what
the engine actually reports it can write.

38 engine tests cover geometry, resampling, alpha handling, every output
format, and that a warm reduction cache renders bit-identically to a cold
one. CI runs fmt, Clippy, tests, a wasm build and a site build; pushes to
main deploy to GitHub Pages.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0136PgRWHesdPLprcMp5CDk8
`on: pull_request` and `on: push: branches-ignore: [main]` both match a
push to a PR branch, so every push burned two full runs of the Rust
toolchain. Pull requests are the only place this workflow adds signal:
`main` already runs the test suite through the deploy workflow.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0136PgRWHesdPLprcMp5CDk8
@profradha
profradha merged commit 951e38d into main Aug 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant