Skip to content

feat(capytone): image mode and /color-picker-from-image (D50) - #104

Merged
unfoldingdimensions merged 1 commit into
mainfrom
feat/capytone-image-mode
Oct 9, 2026
Merged

unfoldingdimensions merged 1 commit into
mainfrom
feat/capytone-image-mode

Conversation

@unfoldingdimensions

Copy link
Copy Markdown
Owner

CapyTone gets a sixth mode, Image: drop, paste or pick a photo → a ranked palette (click a swatch to copy its hex, or copy all as CSS variables / Tailwind tokens), and click — or arrow-key — any pixel for its hex, rgb() and hsl(). Plus the intent page /color-picker-from-image ("color picker from image": 100K–1M/month on Google). D50, L39, L40.

How

  • Entirely in the tab: decodeImage (CapyResize's), canvases, no route, no upload, no storage. The palette is sampled from a 400 px copy; a pick reads the original pixel (1×1 source rect from the decoded image).
  • rank.ts: clustering split out as rankCounts(counts, deltaE); image mode merges at ΔE00 10. Clusters are now re-sorted by merged count before the 12-cap (L40) — Extract's order can change in that case.
  • export.ts: cssVariables / tailwindColors generalised; the mood exporters call them (output unchanged).
  • tests/capytone-image-boundaries.test.ts walks the transitive import graph and fails on any Extract server module, node:/next/server, request API or web storage.

Verified

  • vitest 2048/2048, eslint clean, next typegen && tsc --noEmit clean.
  • Dev server: /color-picker-from-image opens on Image mode; a dropped 200×100 PNG (150 px #c07952, 50 px #5f7a72) gave swatches 75% / 25%, a click at 90% width picked #5f7a72, and no non-blob request was made. The authoring session also verified three picks on a 6048×4024 photo against an independent createImageBitmap read (D50).

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@unfoldingdimensions
unfoldingdimensions merged commit 70f8bc6 into main Oct 9, 2026
3 checks passed
@unfoldingdimensions
unfoldingdimensions deleted the feat/capytone-image-mode branch October 9, 2026 10:18
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