pub mod color;
pub mod kmeans;
pub mod swatch;
use color::Rgb;
use kmeans::{ColorSpace, InitMethod};
use swatch::Swatch;
pub fn generate_swatches(
pixels: &[Rgb],
count: usize,
color_space: ColorSpace,
init: InitMethod,
seed: u64,
) -> Vec<Swatch> {
let mut swatches: Vec<Swatch> = kmeans::extract_colors(pixels, count, color_space, init, seed)
.into_iter()
.map(|(color, pop)| Swatch::new(color, pop))
.collect();
swatches.sort_by(|a, b| b.population.cmp(&a.population));
swatches
}
pub fn pixels_from_rgba(data: &[u8]) -> Vec<Rgb> {
data.chunks_exact(4)
.map(|chunk| Rgb::new(chunk[0], chunk[1], chunk[2]))
.collect()
}
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
#[cfg(feature = "wasm")]
#[wasm_bindgen(js_name = generateSwatches)]
pub fn generate_swatches_wasm(
rgba_data: &[u8],
count: usize,
color_space: &str,
init_method: &str,
seed: u64,
) -> String {
let pixels = pixels_from_rgba(rgba_data);
let cs = match color_space {
"lab" => ColorSpace::Lab,
"lab-ciede2000" => ColorSpace::LabCIEDE2000,
_ => ColorSpace::Rgb,
};
let init = match init_method {
"random" => InitMethod::Random,
_ => InitMethod::KMeansPlusPlus,
};
let swatches = generate_swatches(&pixels, count, cs, init, seed);
let entries: Vec<String> = swatches
.iter()
.map(|s| {
format!(
r#"{{"hex":"{}","r":{},"g":{},"b":{},"population":{}}}"#,
s.hex(),
s.color.r,
s.color.g,
s.color.b,
s.population
)
})
.collect();
format!("[{}]", entries.join(","))
}