Skip to content

Add palette quantization and automatic shading tools#8

Merged
willibrandon merged 5 commits into
mainfrom
feature/palette-quantization-auto-shading
Oct 18, 2025
Merged

Add palette quantization and automatic shading tools#8
willibrandon merged 5 commits into
mainfrom
feature/palette-quantization-auto-shading

Conversation

@willibrandon
Copy link
Copy Markdown
Owner

Summary

Adds two new MCP tools for advanced pixel art workflows:

  1. quantize_palette - Reduces sprite colors using industry-standard algorithms
  2. apply_auto_shading - Automatically adds geometry-based shading to sprites

Fixes #7

Changes

New Tools

quantize_palette:

  • Three quantization algorithms: median_cut, k-means, octree
  • Support for 2-256 color palettes
  • Optional Floyd-Steinberg dithering
  • Transparency preservation
  • Automatic conversion to indexed or RGB color mode

apply_auto_shading:

  • Geometry-based surface analysis with flood fill region detection
  • Per-pixel normal calculations for spherical surfaces
  • Three shading styles: cell (hard bands), smooth (dithered), soft (gradient)
  • Eight light directions: top_left, top, top_right, left, right, bottom_left, bottom, bottom_right
  • Adjustable intensity (0.0-1.0)
  • Optional hue shifting (shadows→cool, highlights→warm)

Bug Fixes

  • Fixed ImportImage color mode conversion using BlendMode.SRC for proper indexed→RGB palette handling
  • Fixed ApplyAutoShadingResult to create new cel instead of drawing onto existing cel
  • Added RGB conversion step for quantized sprite exports to prevent palette mismatch

Examples

  • examples/quantization/ - Demonstrates all three algorithms with side-by-side comparison
  • examples/shading/ - Shows all styles, intensities, light directions, and hue shifting effects

Testing

  • Unit tests for quantization algorithms with transparency and dithering
  • Integration tests for both tools using real Aseprite
  • Example programs generate visual output for manual verification

Output Examples

Quantization:

  • Side-by-side comparison: Original | Median Cut | K-means | Octree
  • Color reduction: 16,000 colors → 4, 8, or 16 colors
  • With/without Floyd-Steinberg dithering

Shading:

  • Cell shading on sphere, cube, capsule shapes
  • Smooth shading with varying intensities (0.3, 0.6, 0.9)
  • All 8 light direction comparison
  • Hue shift comparison (with/without)

Documentation

  • Updated CHANGELOG.md with version 0.4.0
  • Updated README.md features section
  • Added detailed sections to examples/README.md
  • Updated CLAUDE.md with implementation details

Adds quantize_palette tool with three algorithms (median_cut, k-means, octree) and optional Floyd-Steinberg dithering.

Adds apply_auto_shading tool with geometry-based shading, per-pixel normal calculations, three styles, and eight light directions.

Fixes ImportImage color mode conversion using BlendMode.SRC for proper indexed-to-RGB palette handling.

Includes examples and integration tests for both tools.

Fixes #7
@willibrandon willibrandon self-assigned this Oct 18, 2025
@willibrandon willibrandon added the enhancement New feature or request label Oct 18, 2025
Updates ImportImage test assertions to match new cel creation pattern.

Fixes MedianCutQuantization to stop splitting when all colors are identical instead of continuing to request more buckets.

Corrects CountUniqueColors test to use three distinct opaque colors instead of mixing transparent and opaque black pixels.
@willibrandon willibrandon requested a review from Copilot October 18, 2025 20:03
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds two new MCP tools to enhance pixel art workflows: palette quantization and automatic shading. Also updates import behavior, examples, and documentation.

  • New tools: quantize_palette (median_cut, kmeans, octree; optional dithering; transparency handling; indexed conversion) and apply_auto_shading (3 styles, 8 light directions, intensity, optional hue shift)
  • Bug fixes: ImportImage color conversion and ApplyAutoShadingResult cel creation
  • Examples and tests: Integration and unit tests; example programs producing visual outputs

Reviewed Changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/tools/quantization.go Implements quantize_palette tool and image export/quantize/apply flow
pkg/tools/auto_shading.go Implements apply_auto_shading tool and shaded image apply flow
pkg/tools/quantization_integration_test.go Integration tests for quantization algorithms and dithering
pkg/tools/auto_shading_integration_test.go Integration tests for auto-shading styles and directions
pkg/server/server.go Registers new tools with MCP server
pkg/aseprite/quantization.go Core quantization algorithms and helpers (median cut, octree, dithering utils)
pkg/aseprite/quantization_test.go Unit tests and benchmarks for quantization and dithering utilities
pkg/aseprite/lua_quantization.go Lua generator to apply quantized palette and report JSON
pkg/aseprite/lua_auto_shading.go Lua generator to apply shaded result and report JSON
pkg/aseprite/lua_export.go Fixes ImportImage to use newCel with converted image
pkg/aseprite/lua_canvas.go Adds FlattenLayers Lua helper
examples/quantization/main.go End-to-end example for quantization comparisons
examples/shading/main.go End-to-end example for auto-shading comparisons
examples/README.md Documents the new examples and outputs
README.md Adds quantization and auto-shading features to overview
CLAUDE.md Documents new modules and patterns
CHANGELOG.md Bumps to 0.4.0 with features and fixes
Comments suppressed due to low confidence (2)

pkg/aseprite/lua_quantization.go:1

  • Go's fmt.Sprintf will eagerly consume the %s placeholders intended for Lua's string.format, resulting in missing arguments and malformed JSON (you only pass two runtime args: colorMode and the palette string). Escape the two Lua-side placeholders as %%s so Go leaves them intact, and ensure the remaining placeholders are satisfied by the Go fmt arguments. For example, change lines 114-115 to use "%%s" and "[%%s]" respectively; keep original_colors, quantized_colors, and algorithm_used filled by Go.
package aseprite

pkg/aseprite/lua_auto_shading.go:1

  • Same formatting issue as in ApplyQuantizedPalette: Go's fmt.Sprintf will treat %s as its own placeholder, but you only supply two integers (colors_added and regions_shaded) to the outer fmt. Escape the Lua-side %s as %%s so the palette is provided by Lua string.format at runtime, and keep the two %d placeholders satisfied by the Go fmt arguments.
package aseprite

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread pkg/aseprite/quantization.go Outdated
Comment thread pkg/tools/quantization.go
Comment thread pkg/tools/auto_shading.go Outdated
Comment thread pkg/tools/quantization.go Outdated
- Implement Floyd-Steinberg dithering with pixel remapping
- Add ReplaceWithImage function to apply dithered results back to sprite
- Set default values for preserve_transparency and convert_to_indexed
- Remove redundant file close in auto_shading
- Use gen.ExportSprite instead of inline Lua script for consistency
- Add integration test covering full dithering workflow
The dither parameter was never used in QuantizePalette since the
function only computes a color palette and doesn't modify image pixels.
Dithering is applied separately at the tool layer via
RemapPixelsWithDithering when input.Dither is true.
Test was hanging due to 4,096 separate ExecuteLua calls to draw
individual pixels. Now batches all pixels into a single DrawPixels call.
Also updates function signatures to match current API.
@willibrandon willibrandon merged commit de483bb into main Oct 18, 2025
2 checks passed
@willibrandon willibrandon deleted the feature/palette-quantization-auto-shading branch October 18, 2025 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add automatic palette quantization and shading tools

2 participants