Skip to content

Add halogen-image module for image-to-theme extraction#19

Open
himattm wants to merge 1 commit intomainfrom
feature/halogen-image
Open

Add halogen-image module for image-to-theme extraction#19
himattm wants to merge 1 commit intomainfrom
feature/halogen-image

Conversation

@himattm
Copy link
Copy Markdown
Owner

@himattm himattm commented Apr 9, 2026

Summary

  • New halogen-image KMP module that extracts dominant colors from images and maps them to Halogen themes
  • Uses HCT-space k-means clustering for perceptually accurate color extraction (~0.8ms regardless of image size)
  • Coil 3 integration for URL-based image loading with platform-specific pixel extraction (Android/JVM/iOS/wasmJs)
  • Two paths: algorithmic (toSpec() — instant, no LLM) and LLM-enhanced (toHint() — mood-aware typography/shapes)

API

// Music player — one line, URL is the cache key
engine.resolveImage(album.artUrl, imageLoader, context)

// Raw pixels (for non-Coil loaders)
engine.resolveImage("album:123", pixels, width, height)

// Standalone extraction
val colors = ImageQuantizer.extract(pixels, w, h)
colors.toSpec()   // algorithmic
colors.toHint()   // enriched LLM hint

Module structure

  • ImageQuantizer — histogram + HCT k-means clustering (subsamples to 16K pixels, 64 histogram entries, 10 iterations)
  • ImageThemeExtractor — assigns extracted colors to pri/sec/ter/neutral roles by chroma/hue/tone heuristics
  • DominantColors — result type with toSpec() and toHint() conversions
  • EngineExtensionsresolveImage() overloads on HalogenEngine
  • Platform expect/actual for Coil image → ARGB pixel extraction

Performance

Image size Extraction time
500×500 0.80ms
1080×1080 0.86ms

Tests

38 test cases across 3 files covering extraction algorithm, role assignment heuristics, round-trip validation through ThemeExpander.expand().

Test plan

  • ./gradlew :halogen-image:jvmTest — all 38 tests pass
  • ./gradlew :halogen-image:testReleaseUnitTest — Android tests pass
  • ./gradlew :halogen-image:apiCheck — API surface validated
  • Existing module tests unaffected (halogen-core, halogen-engine)
  • wasmJs browser tests have pre-existing Skiko resolution issue (same as halogen-compose)

🤖 Generated with Claude Code

Enables theming from images (e.g., album art in music players) by extracting
dominant colors and mapping them to HalogenThemeSpec roles. Uses HCT-space
k-means clustering for perceptually accurate color extraction (~0.8ms).

Two paths: algorithmic (instant, offline via toSpec()) or LLM-enhanced
(mood-aware typography/shapes via toHint()). Coil 3 integration for
URL-based image loading with platform-specific pixel extraction.

API:
  engine.resolveImage(url, imageLoader, context) — Coil URL path
  engine.resolveImage(key, pixels, width, height) — raw pixels path
  ImageQuantizer.extract(pixels, w, h) — standalone extraction
  DominantColors.toSpec() / .toHint() — conversion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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