Commit Graph
387 Commits
Author SHA1 Message Date
ashim-hq e529fbb839 docs: add resource footprint section — idle memory, lazy model loading, cold start behavior 2026-04-16 16:51:18 +08:00
ashim-hq 9d84dc262f docs: add Contributing page, no-PR policy, link from sidebar 2026-04-16 16:40:53 +08:00
ashim-hq e52bce555b docs: rewrite translations guide - no PRs, open issues for translation requests 2026-04-16 16:40:43 +08:00
ashim-hq c8dd454f74 docs: replace em dashes with hyphens throughout 2026-04-16 16:40:18 +08:00
ashim-hq 7d1b9e6dc3 docs: update architecture — 47 tools, user file library, teams, branding, runtime settings 2026-04-16 16:29:04 +08:00
ashim-hq 956b7572ca docs: remove non-existent updatedAt from teams and user_files tables 2026-04-16 16:27:50 +08:00
ashim-hq 697b13de7a docs: add teams + user_files tables, fix jobs.progress type (real 0-1) 2026-04-16 16:26:58 +08:00
ashim-hq a2d41575a2 docs: add MAX_USERS and SKIP_MUST_CHANGE_PASSWORD to configuration reference 2026-04-16 16:26:02 +08:00
ashim-hq 5e8676a33e docs: rewrite AI engine reference — 13 AI tools including colorize, restore, noise-removal, passport-photo 2026-04-16 16:24:47 +08:00
ashim-hq cd72bea975 docs: rewrite REST API reference — 47 tools, user-files, teams, branding, settings, permissions 2026-04-16 16:21:29 +08:00
ashim-hq 205c26023e docs: rewrite getting-started — 45+ tools table, file library, teams, API keys 2026-04-16 16:17:43 +08:00
ashim-hq 26068ad239 docs: fix AI tool count (13 not 14), update llms template to 45+ tools 2026-04-16 16:16:13 +08:00
ashim-hq f4b4890070 docs: update homepage — A Self Hosted Image Manipulator, 45+ tools, 6 feature cards 2026-04-16 16:13:33 +08:00
Siddharth Kumar Sah 9cd91edee1 chore(release): 1.15.0
Bump all workspace packages from 1.14.0 to 1.15.0.
2026-04-15 23:17:31 +08:00
Siddharth Kumar Sah 251445b092 fix(noise-removal): write denoised output to workspace path and add e2e test 2026-04-15 23:11:40 +08:00
Siddharth Kumar Sah ea98e9b5de feat(watermark): overhaul settings UI with improved controls 2026-04-15 23:11:31 +08:00
Siddharth Kumar Sah a8cca62336 feat(erase-object): auto-center compare slider at erased region
Track the painted mask centroid and initialise the before/after slider
at that position so the result is immediately visible without manual
dragging.
2026-04-15 23:11:27 +08:00
Siddharth Kumar Sah 0cf7156b7e fix(preview): show image preview instead of 'Conversion complete' for blob URLs
canBrowserPreview() was checking for a file extension in blob: URLs, which
have none (blob:http://localhost:1349/<uuid>). This caused the optimize-for-web
live preview — which stores a blob: URL in processedUrl — to always return false
and show the 'Conversion complete' fallback card instead of the BeforeAfterSlider.

Fix: blob: URLs are always renderable in <img> tags; short-circuit the extension
check with `if (url.startsWith('blob:')) return true` in both tool-page.tsx and
multi-image-viewer.tsx.
2026-04-15 18:52:36 +08:00
Siddharth Kumar Sah d4ac116c15 chore: remove broken /batch and /pipeline tool stubs
Both routes showed "Tool not found" — the UI was never implemented.
Pipeline functionality already lives at /automate (the Automate page).
Also removed the empty Automation category and unused Workflow/FolderInput
icons from icon-map.ts.
2026-04-15 18:52:36 +08:00
Siddharth Kumar Sah a4c63855d4 fix(docker): fix TDZ crash, icon bundle bloat, rate-limit on static assets
- Fix "Cannot access 'a' before initialization" TDZ error after login
  caused by manualChunks splitting react-vendor + lucide icons into
  circular ES-module chunks. Removed manualChunks entirely.

- Replace `import * as icons from "lucide-react"` (pulls all ~1000 icons)
  with a targeted icon-map of ~50 icons actually used by tool definitions.
  Reduces shared icons chunk from 745KB to 62KB (132KB→16KB gzip).

- Exclude static files from @fastify/rate-limit via allowList so rapid
  page navigations don't 429 on JS/CSS chunk requests.

- Move Docker auth defaults (AUTH_ENABLED, DEFAULT_USERNAME,
  DEFAULT_PASSWORD) from Dockerfile ENV to entrypoint.sh runtime exports
  to avoid SecretsUsedInArgOrEnv warnings.

- Fix Docker CMD to use pnpm --filter for workspace-scoped tsx binary.

- Set COREPACK_HOME system-wide so non-root user can access pnpm cache.

- Lazy-load all pages in App.tsx and all controls in
  pipeline-step-settings.tsx to keep main bundle under 300KB.
2026-04-15 18:52:36 +08:00
Siddharth Kumar Sah 93c588b239 fix(lint): resolve all biome warnings across API, web, and image-engine
API:
- Replace string concatenation with template literals (batch, pipeline,
  tool-factory, content-aware-resize, passport-photo, remove-background)
- Remove unused imports (teams, color-adjustments, image-enhancement)
- Replace non-null assertions with guard clauses in bg-effects and stitch
- Use optional chaining in docs route

Image-engine:
- Remove unused OutputFormat imports (compress, convert)
- Use local variables instead of reassigning parameters (optimize-for-web, sharpen)

Web:
- Fix useExhaustiveDependencies: remove genuinely redundant deps, add
  biome-ignore comments for intentional patterns (src prop, cleanup fns)
- Replace non-null assertions with null-safe alternatives
- Add accessible titles to inline SVGs (color-settings, image-enhancement-settings)
- Fix noLabelWithoutControl: associate labels via htmlFor/id or use <span>
  (image-to-base64-settings, edit-metadata-settings, qr-generate-settings)
- Replace div[role="button"] with <button> (pdf-to-image-settings)
- Use stable keys instead of array indices (collage-preview, collage-settings)
- Fix noStaticElementInteractions in collage-preview (role="none")
- Remove unused function parameters and imports
2026-04-14 22:15:37 +08:00
Siddharth Kumar Sah 3982ff4136 fix(lint): fix import ordering broken by @stirling-image → @ashim rename
The package scope rename changed the alphabetical position of imports
(@ashim sorts before @dnd-kit; @stirling-image sorted after), causing
biome's organizeImports rule to flag them as unsorted.

- apps/api/src/index.ts: sort registerRestorePhoto import correctly
- apps/web/src/components/tools/pipeline-builder.tsx: sort @ashim/shared import
- apps/web/src/pages/privacy-policy-page.tsx: auto-format
2026-04-14 22:01:04 +08:00
Siddharth Kumar Sah 85b1cfc10a chore: rename Stirling-Image to ashim across entire codebase
Complete rebrand from Stirling-Image to ashim following the project
move to https://github.com/ashim-hq/ashim.

Changes across 117 files:
- Package scope: @stirling-image/* → @ashim/*
- GitHub URLs: stirling-image/stirling-image → ashim-hq/ashim
- Docker Hub: stirlingimage/stirling-image → ashimhq/ashim
- GitHub Pages: stirling-image.github.io → ashim-hq.github.io
- All branding text: "Stirling Image" → "ashim"
- Docker service/volumes/user: stirling → ashim
- Database: stirling.db → ashim.db
- localStorage keys: stirling-token → ashim-token
- Environment variables: STIRLING_GPU → ASHIM_GPU
- Python cache dirs: .cache/stirling-image → .cache/ashim
- SVG filter IDs, test prefixes, and all other references
2026-04-14 20:55:42 +08:00
Siddharth Kumar Sah da4411330f feat(collage): overhaul collage tool with preview panel and enhanced settings
Apply stash from feat/border-redesign branch. Rewrites collage backend
with improved layout engine and adds CollagePreview results panel for
interactive preview. Updates tool registry to use no-dropzone display
mode with the new preview component.
2026-04-14 20:47:36 +08:00
stirling-image c6386fa98e fix(optimize-for-web): break infinite preview loop caused by store dependency cycle
The debounce effect depended on currentEntry (from the file store), but
fetchPreview wrote back to the same store entry on completion. This
created a loop: preview completes -> store updates -> new entry ref ->
effect re-fires -> new preview. Fix by reading the file from a ref
instead of reactive state, so the effect only triggers on actual
settings changes (format, quality, dimensions, metadata toggle).
2026-04-14 16:20:25 +08:00
5be8be3dc3 feat: add Optimize for Web tool (#68)
* feat(image-engine): add OptimizeForWebOptions type

* feat(image-engine): add optimizeForWeb operation

* feat(shared): add optimize-for-web tool definition and i18n

* feat(api): add optimize-for-web route with preview endpoint

* feat(web): add optimize-for-web settings component with live preview

* feat(web): register optimize-for-web in tool registry

* fix(web): align toggle switch translate with codebase pattern

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-14 16:16:04 +08:00
stirling-image c2c104e887 fix(passport-photo): use bg-background for dropdown to match app theme 2026-04-14 16:01:35 +08:00
stirling-image e7c1efaaf3 feat(passport-photo): true WYSIWYG - zoom and drag affect the download
- Zoom now controls the actual crop: zoom in = tighter crop, zoom out = more body
- Drag adjusts face position within the frame
- Backend receives zoom value and applies the same zoomed crop
- Download produces exactly what the user sees on the canvas
- Zoom range 0.5x-3x (can zoom out to show more body)
- "What you see is what you download" label
2026-04-14 15:58:31 +08:00
stirling-image 74a6d422c2 feat(passport-photo): restore zoom for visual inspection with clear download disclaimer 2026-04-14 15:52:41 +08:00
stirling-image 4000696bc7 fix(passport-photo): make preview WYSIWYG - remove zoom, what you see is what you download
- Removed zoom controls entirely from preview pane
- Canvas always shows exact passport photo output at 1:1
- Drag to adjust position still works for fine-tuning
- Overlay lines use crop coordinates directly instead of zoom-adjusted ones
- Added "what you see is what you download" label with output dimensions
2026-04-14 15:49:42 +08:00
stirling-image d6498324ca fix(passport-photo): restrict zoom to 1x-3x so preview matches download exactly 2026-04-14 15:45:33 +08:00
stirling-image bb11e086f9 fix(passport-photo): replace circular compliance checks with source photo validation
Old checks validated head height and eye position against the auto-computed
crop, so they always passed. New checks validate the source photo itself:
face centered, head level (eyes same height), looking straight (nose between
eyes), and face size (large enough for quality crop). Adds detail text on
failed checks and updates the canvas overlay to show eye-level and center
indicators instead of the old crown/chin/eye lines.
2026-04-14 15:41:31 +08:00
stirling-image dd51175f16 feat(passport-photo): add custom dimensions, DPI control, fix crop mismatch
- Added "Custom Dimensions" option in country dropdown with width/height inputs
- Added DPI control (72-600, default 300) for all specs
- Backend now uses actual bg-removed image dimensions for crop computation,
  scaling landmark coordinates when dimensions differ from the original
- Dropdown background uses explicit bg-white/dark:bg-zinc-900 classes
- Backend supports customWidthMm, customHeightMm, and dpi in generate request
2026-04-14 15:28:21 +08:00
stirling-image f6cc30e79c fix(passport-photo): fix preview-download mismatch, dropdown bg, scroll hint
- Backend now pads the image with background color when crop region extends
  beyond image bounds, instead of clamping (which cut off heads)
- Dropdown uses explicit bg-white/dark:bg-zinc-900 instead of CSS variable
  that was transparent on some themes
- Added "Scroll to zoom" hint on the right pane canvas
- Fixed file size compression loop to use padded source image
2026-04-14 15:18:36 +08:00
stirling-image e17d5d08cb fix(passport-photo): fix dropdown overlap, add common bg colors, fix zoom behavior
- Country dropdown now uses position:fixed with z-index:9999 to render above all siblings
- Added 5 common passport background color presets (white, off-white, light gray, light blue, red)
- Zoom now crops into the image center rather than scaling the canvas element
- Compliance overlay lines are zoom-aware
2026-04-14 13:04:35 +08:00
stirling-image 831ef3f2de refactor(passport-photo): rebuild UI for online applications with file size control 2026-04-14 12:55:37 +08:00
b2489b0fb6 feat(image-to-base64): progress bar, synced navigation, batch download buttons (#66)
- Process files one at a time for real per-file progress bar
- Sync right panel with left panel file navigation (arrows work)
- Show image preview before conversion
- Add "Download All as JSON" and "Download All as Text" batch buttons
- Unify batch action button styles

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-14 12:19:20 +08:00
stirling-image c09c1be4d2 fix(passport-photo): fix dropdown overlap, add zoom controls to preview
- Add z-30 to country dropdown container to prevent overlap with settings below
- Add mouse wheel zoom on preview canvas (0.5x to 3x)
- Add zoom in/out buttons and reset with percentage display
- Update hint text to "Drag / Scroll to zoom"
2026-04-14 11:55:04 +08:00
01cbb16cd9 feat: SOTA Image to Base64 converter with 6 output formats (#65)
* feat(image-to-base64): register tool in shared constants and i18n

* feat(image-to-base64): add API route with Sharp pipeline and base64 encoding

* feat(image-to-base64): add Zustand store for base64 results

* feat(image-to-base64): add settings panel component

* feat(image-to-base64): add results panel with 6-tab output and batch accordion

* feat(image-to-base64): register tool in frontend tool registry

* fix(image-to-base64): pass through original buffer when no resize/conversion needed

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-14 10:17:19 +08:00
2f11b9e101 feat(passport-photo): SOTA passport photo maker with compliance validation (#64)
* feat(passport-photo): add passport specs database and tool constants

* feat(passport-photo): add MediaPipe FaceMesh landmark detection script

* feat(passport-photo): add TypeScript bridge for face landmark detection

* feat(passport-photo): add API routes with analyze and generate endpoints

* fix(passport-photo): accept landmarks from request body and fix pixel coordinate conversion

- Generate endpoint now accepts landmarks + imageWidth/imageHeight in request body
  instead of re-running AI face detection (makes generate phase instant)
- Fixed bug where normalized landmark coordinates (0-1) were used directly
  as pixel values in crop computation - now properly multiplied by imgW/imgH
- Fixed same bug in pipeline process function

* feat(passport-photo): add UI component with live preview and compliance overlay

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-14 09:59:48 +08:00
6a43cc1b77 feat: SOTA AI photo restoration with multi-step pipeline (#58) (#62)
Add comprehensive photo restoration tool that chains multiple AI models:
- Scratch/tear/spot detection via morphological analysis (top-hat/black-hat transforms)
- Damage inpainting via LaMa ONNX model (reuses existing infrastructure)
- Face enhancement via CodeFormer ONNX (~377MB, from facefusion/models-3.0.0)
- Noise reduction via OpenCV NLMeans in LAB color space
- Optional B&W auto-colorization via DDColor (reuses existing model)

Settings: 3 restoration modes (Light/Auto/Heavy), individual feature toggles
for scratch removal, face enhancement (with fidelity slider), denoising
(with strength slider), and auto-colorize. Before/after comparison view.

Handles HEIC, HEIF, and all standard formats. Batch processing supported.
No new Python dependencies - reuses onnxruntime, cv2, mediapipe, PIL.

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 21:57:51 +08:00
8071fe61c5 feat: AI face enhancement with GFPGAN and CodeFormer (#61)
* feat(shared): add enhance-faces tool definition and i18n strings

* feat(ai): add face enhancement script with GFPGAN and CodeFormer support

Detects faces via MediaPipe dual-model approach, then enhances using
GFPGAN (proven) or CodeFormer (via codeformer-pip) with auto fallback.
Supports strength-based alpha blending with original image.

* feat(ai): add TypeScript bridge for face enhancement

* feat(api): add enhance-faces route with GFPGAN/CodeFormer support

* feat(web): add enhance-faces settings component and register in tool registry

* feat(docker): add CodeFormer dependency and model download

- Add codeformer-pip to both CPU and GPU requirements
- Download CodeFormer model (~375MB) at Docker build time
- Add CodeFormer to smoke test verification

* fix(enhance-faces): address code review findings

- Skip alpha blend for CodeFormer (strength already applied via fidelity weight)
- Hide "only enhance main face" checkbox when Best (CodeFormer) is selected
- Fix sensitivity slider labels (swap More/Fewer faces to match actual behavior)
- Register EnhanceFacesControls in pipeline step settings
- Remove model names from user-facing descriptions

* fix(enhance-faces): fix CodeFormer integration and Docker setup

- Add codeformer-pip install to Dockerfile with --no-deps to avoid numpy 2.x conflict
- Re-pin numpy==1.26.4 after codeformer-pip install
- Pin codeformer-pip==0.0.4 in requirements files
- Broaden auto-mode fallback to catch any Exception from CodeFormer

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 21:56:59 +08:00
9ddeac92b6 feat(red-eye-removal): SOTA red eye removal with MediaPipe Face Mesh + OpenCV LAB correction (#60)
Uses MediaPipe Face Mesh (refine_landmarks=True) for precise iris localization
and OpenCV LAB color space for accurate red-eye detection and luminance-preserving
correction. Zero new dependencies - leverages existing MediaPipe + OpenCV stack.

- Sensitivity slider (LAB 'a' channel threshold)
- Correction strength slider (pupil darkening factor)
- Output format selector (Original/PNG/JPEG/WebP)
- Before/after preview, progress stages, batch processing
- Pipeline support via Controls/Settings split

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 20:22:30 +08:00
dfffc0a8cc feat(noise-removal): SOTA noise removal with 4 quality tiers (#57)
* feat(noise-removal): register tool in shared constants and i18n

* feat(noise-removal): add SCUNet and NAFNet model architectures

* feat(noise-removal): add Python denoising engine with 4 quality tiers

* feat(noise-removal): add TypeScript bridge for Python sidecar

* feat(noise-removal): add frontend settings with 4-tier selector

* feat(noise-removal): register in tool registry and pipeline

* feat(noise-removal): add Fastify API route with Zod validation

* feat(noise-removal): add SCUNet and NAFNet model downloads to Docker build

* test(noise-removal): add to e2e tool page rendering tests

* test(noise-removal): add integration tests for API endpoint

* style: fix biome formatting and import ordering

* fix(noise-removal): use correct model download URLs

NAFNet model is hosted on HuggingFace, not GitHub releases.
Also align SCUNet URL to use the KAIR releases (same as Docker build).

* fix(noise-removal): remove emojis from tier selector, simplify labels

Drop emoji icons from Quick/Balanced/Quality/Maximum buttons. Replace
technical algorithm names with plain descriptions users can understand.

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 19:50:23 +08:00
stirling-image 61794dca2d fix(colorize): use user-friendly model labels (Fast/Balanced/Best) 2026-04-13 19:48:48 +08:00
c280076098 feat: SOTA AI photo colorization with DDColor deep learning model (#57) (#58)
Add AI-powered photo colorization that converts B&W/grayscale images to
full color using DDColor (ICCV 2023 dual-decoder architecture) via ONNX
Runtime. Includes model selection (Auto/DDColor/Classic), adjustable color
intensity, batch processing, before/after preview, and full HEIC/HEIF support.

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 19:40:55 +08:00
58cdbe50b4 feat: SOTA sharpening tool with 3 methods and 7 presets (#56)
* feat(sharpening): add SharpenAdvancedOptions type for multi-method sharpening

* feat(sharpening): implement 3-method sharpen engine (adaptive, USM, high-pass)

* feat(sharpening): add dedicated API route with Zod validation

* feat(sharpening): register tool in constants, i18n, and suggested tools

* feat(sharpening): add settings UI with presets, methods, and advanced controls

* feat(sharpening): register tool in frontend registry with before-after display

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 19:12:09 +08:00
a8c7b92ca5 feat: SOTA image enhancement with one-click auto-improve (#55)
* feat(image-enhancement): add analysis and correction types

* feat(image-enhancement): implement auto-enhance analysis and correction engine

* test(image-enhancement): add unit tests for auto-enhance engine

* feat(image-enhancement): add API route with analyze endpoint and register in constants/i18n

* feat(image-enhancement): add UI component with mode selector, intensity slider, and analysis badges

* test(image-enhancement): add integration and e2e tests

* fix(image-enhancement): use modulate instead of gamma for exposure correction

Sharp's gamma() only accepts values between 1.0 and 3.0, but brightening
underexposed images computed gamma < 1.0. Switch to modulate({ brightness })
which handles both brightening and darkening correctly.

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 17:48:53 +08:00
34ec840b72 docs(api): achieve 100% endpoint coverage in OpenAPI spec and VitePress docs (#54)
Add 12 previously undocumented routes to the OpenAPI 3.1 specification:
content-aware-resize, edit-metadata (+ inspect), stitch, pdf-to-image
(+ info, preview), gif-tools/info, remove-background/effects, preview,
pipeline/tools, and pipeline/batch. Fix license from MIT to AGPL-3.0,
correct DELETE /files response from 204 to 200 with body, and update
VitePress API docs (rest.md tool table, ai.md model parameters). Also
register the sharpen operation in the image-engine OPERATION_MAP so it
can be used as a standalone pipeline step.

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 17:30:08 +08:00
Siddharth Kumar Sah cd886f0f82 fix(pipeline): route content-aware resize correctly and improve error messages
- Route resize steps with contentAware=true to the content-aware-resize
  tool in both single-file and batch pipeline paths
- Update HEIC filename extension to .png after decoding so downstream
  tools don't attempt double-decoding
- Wrap per-step errors with step number and tool name for clarity
  (e.g. "Step 1 (resize): Resize requires width, height, or percentage")
- Show first file's step-level error in batch failure messages
2026-04-13 17:04:11 +08:00