swatchthis 0.1.0

Colour swatch extraction from images using k-means clustering
Documentation
  • Coverage
  • 60%
    21 out of 35 items documented8 out of 19 items with examples
  • Size
  • Source code size: 45.01 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 3.11 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 12s Average build duration of successful builds.
  • all releases: 1m 26s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • OwenElliottDev

swatchthis

A Rust library for extracting dominant colour swatches from images using k-means clustering. Works in native Rust and WebAssembly.

Features

  • K-means and k-means++ centroid initialisation
  • RGB and CIELAB colour space clustering
  • CIEDE2000 Distance for CIELAB, slower but good perceptual accuracy
  • WebAssembly support via wasm-bindgen (behind the wasm feature flag)
  • No runtime dependencies for native builds (deterministic PRNG, no rand crate)

Usage

Add to your Cargo.toml:

[dependencies]
swatchthis = "0.1"

Extract swatches from raw RGBA pixel data

use swatchthis::{generate_swatches, pixels_from_rgba};
use swatchthis::kmeans::{ColorSpace, InitMethod};

let rgba_data: &[u8] = &[/* RGBA bytes from an image */];
let pixels = pixels_from_rgba(rgba_data);

let swatches = generate_swatches(
    &pixels,
    6,                          // number of swatches
    ColorSpace::Lab,            // cluster in CIELAB space
    InitMethod::KMeansPlusPlus, // k-means++ init
    42,                         // seed for deterministic results
);

for swatch in &swatches {
    println!("{}{} pixels", swatch.hex(), swatch.population);
}

Work with colours directly

use swatchthis::color::Rgb;

let red = Rgb::new(255, 0, 0);
let lab = red.to_lab();
let back = lab.to_rgb();
assert_eq!(red, back);

println!("{}", red.to_hex()); // #ff0000

Lower-level clustering

use swatchthis::color::Rgb;
use swatchthis::kmeans::{extract_colors, ColorSpace, InitMethod};

let pixels: Vec<Rgb> = vec![/* ... */];
let results = extract_colors(&pixels, 4, ColorSpace::Rgb, InitMethod::Random, 1);

for (color, population) in &results {
    println!("{} ({}px)", color.to_hex(), population);
}

WebAssembly

Enable the wasm feature and build with wasm-pack:

wasm-pack build --target web --features wasm

The WASM module exposes a generateSwatches function:

import init, { generateSwatches } from './pkg/swatchthis.js';

await init();

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

const json = generateSwatches(imageData.data, 6, "lab", "kmeans++", 42n);
const swatches = JSON.parse(json);
// [{ hex: "#ff0000", r: 255, g: 0, b: 0, population: 1234 }, ...]

A demo app is included in demos/web/. Build it with:

bash demos/web/build.sh
cd demos/web && python3 -m http.server 8080

Licence

MIT