A fast, cross-platform CLI tool that extracts dominant colors from images using k-means clustering.
go install github.com/james-see/swatchify@latestbrew install james-see/tap/swatchifyDownload the latest release for your platform from the Releases page.
git clone https://github.com/james-see/swatchify
cd swatchify
go build -o swatchify .swatchify <image> [flags]# Extract 5 dominant colors (default)
swatchify photo.jpg
# Extract 8 colors
swatchify logo.png -n 8
# Output as JSON
swatchify image.png --json
# Generate a palette PNG with hex labels
swatchify brand.png --png palette.png
# Generate palette and open it
swatchify brand.png --png palette.png --show
# Exclude white and black colors
swatchify mood.png --exclude-white --exclude-black
# Higher quality (slower, more accurate)
swatchify photo.jpg --quality 100
# Pipe JSON to file
swatchify image.jpg --json > palette.json| Flag | Short | Default | Description |
|---|---|---|---|
--colors |
-n |
5 | Number of dominant colors to extract |
--json |
false | Output in JSON format | |
--png |
Generate palette PNG at specified path | ||
--exclude-white |
false | Exclude colors close to white | |
--exclude-black |
false | Exclude colors close to black | |
--min-contrast |
0 | Minimum color distance between palette colors | |
--show |
false | Open generated palette image after creation | |
--quality |
50 | Downscale quality 0-100 (higher = more accurate, slower) | |
--width |
1000 | Palette image width in pixels | |
--height |
200 | Palette image height in pixels |
- JPEG/JPG
- PNG
- WebP
- GIF (first frame)
- BMP
- TIFF
#112233
#AABBCC
#FFEEDD
#998877
#341212
{
"image": "input.jpg",
"colors": [
{"hex": "#112233", "percentage": 34.5},
{"hex": "#AABBCC", "percentage": 21.0},
{"hex": "#FFEEDD", "percentage": 18.2},
{"hex": "#998877", "percentage": 15.1},
{"hex": "#341212", "percentage": 11.2}
]
}Generates a horizontal color strip with blocks sized proportionally to color prevalence. Each block displays its hex code with automatic contrast text (white on dark, black on light).
- Target execution time: < 300ms for typical images
- Memory footprint: < 100MB
- Images are automatically downscaled for processing speed
Start swatchify as an HTTP server for REST API access:
swatchify serve --port 8080POST /extract — Extract colors from uploaded image
# Basic usage
curl -X POST -F "[email protected]" http://localhost:8080/extract
# With options
curl -X POST \
-F "[email protected]" \
-F "colors=8" \
-F "quality=100" \
-F "exclude_white=true" \
http://localhost:8080/extractResponse:
{
"success": true,
"colors": [
{"hex": "#112233", "percentage": 34.5},
{"hex": "#AABBCC", "percentage": 21.0}
]
}GET /health — Health check
curl http://localhost:8080/health
# {"status": "ok"}| Parameter | Type | Default | Description |
|---|---|---|---|
image |
file | required | Image file to analyze |
colors |
int | 5 | Number of colors to extract |
quality |
int | 50 | Quality 0-100 |
exclude_white |
bool | false | Exclude near-white colors |
exclude_black |
bool | false | Exclude near-black colors |
min_contrast |
float | 0 | Minimum color distance |
Swatchify can be imported and used in your Go code:
package main
import (
"fmt"
"log"
"github.com/james-see/swatchify/pkg/swatchify"
)
func main() {
// Extract with default options (5 colors)
colors, err := swatchify.ExtractFromFile("photo.jpg", nil)
if err != nil {
log.Fatal(err)
}
for _, c := range colors {
fmt.Printf("%s (%.1f%%)\n", c.Hex, c.Percentage)
}
// Custom options
opts := &swatchify.Options{
NumColors: 8,
Quality: 100,
ExcludeWhite: true,
ExcludeBlack: true,
MinContrast: 30,
}
colors, _ = swatchify.ExtractFromFile("photo.jpg", opts)
// Generate palette image
swatchify.GeneratePalette(colors, "palette.png", nil)
}// Extract from file path
colors, err := swatchify.ExtractFromFile(path string, opts *Options) ([]Color, error)
// Extract from image.Image
colors, err := swatchify.ExtractFromImage(img image.Image, opts *Options) ([]Color, error)
// Generate palette PNG
err := swatchify.GeneratePalette(colors []Color, outputPath string, opts *PaletteOptions) error- Load and decode the input image
- Downscale large images based on quality setting
- Extract pixel data as RGB vectors
- Run k-means++ clustering to find dominant colors
- Sort clusters by population percentage
- Apply any filters (white/black exclusion, min contrast)
- Output results in requested format
MIT