diff --git a/CHANGELOG.md b/CHANGELOG.md index dd57ec7..d77e970 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ # Changelog -## [v0.3.0](https://github.com/t28hub/auto-palette/releases/tag/v0.3.0)) +## [v0.4.0](https://github.com/t28hub/auto-palette/releases/tag/v0.4.0) + +* Introduce support for color format conversion to `CMYK`, `ANSI16`, and `ANSI256`. +* Enhance the `Swatch` struct with the addition of a `ratio` field, representing the proportion of the image that the color occupies. +* Add `Theme::Colorful` for a more vibrant color selection in the palette. +* Improve color selection criteria and scoring for better alignment with themes. + +## [v0.3.0](https://github.com/t28hub/auto-palette/releases/tag/v0.3.0) * Add multiple color spaces, including the following: * `HSL` diff --git a/Cargo.toml b/Cargo.toml index e77d556..86fc0c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = ["crates/*"] [workspace.package] edition = "2021" -version = "0.3.0" +version = "0.4.0" authors = ["Tatsuya Maki "] license = "MIT" homepage = "https://github.com/t28hub/auto-palette" @@ -12,7 +12,7 @@ repository = "https://github.com/t28hub/auto-palette" [workspace.dependencies] assert_cmd = "2.0.14" -auto-palette = { version = "0.3.0", path = "crates/auto-palette", default-features = false } +auto-palette = { version = "0.4.0", path = "crates/auto-palette", default-features = false } clap = { version = "4.5.4", features = ["cargo"] } getrandom = "0.2.15" image = "0.25.1" diff --git a/README.md b/README.md index bf0fae1..3da63bd 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ To use `auto-palette` in your Rust project, add it to your `Cargo.toml`. ```toml [dependencies] -auto-palette = "0.3.0" +auto-palette = "0.4.0" ``` ## Usage @@ -47,7 +47,7 @@ fn main() { let image_data = ImageData::load("tests/assets/holly-booth-hLZWGXy5akM-unsplash.jpg").unwrap(); // Extract the color palette from the image data - let palette: Palette = Palette::extract(&image_data).unwrap(); + let palette: Palette = Palette::extract(&image_data).unwrap(); println!("Extracted {} swatches", palette.len()); // Find the 5 dominant colors in the palette and print their information @@ -56,6 +56,7 @@ fn main() { println!("Color: {}", swatch.color().to_hex_string()); println!("Position: {:?}", swatch.position()); println!("Population: {}", swatch.population()); + println!("Ratio: {}", swatch.ratio()); } } ``` diff --git a/crates/auto-palette/Cargo.toml b/crates/auto-palette/Cargo.toml index 111c92c..aed819f 100644 --- a/crates/auto-palette/Cargo.toml +++ b/crates/auto-palette/Cargo.toml @@ -2,7 +2,7 @@ name = "auto-palette" description = "🎨 A Rust library that extracts prominent color palettes from images automatically." readme = "./README.md" -categories = ["multimedia::images", "graphics", "algorithms"] +categories = ["multimedia::images", "graphics", "algorithms", "mathematics"] keywords = ["palette", "color", "image", "color-palette", "color-extraction"] edition.workspace = true version.workspace = true @@ -10,8 +10,11 @@ authors.workspace = true license.workspace = true homepage.workspace = true repository.workspace = true -# `cargo msrv` does not support `rust-version.workspace` yet. -# https://github.com/foresterre/cargo-msrv/issues/590 + +# `cargo msrv` does not support `rust-version.workspace` yet + +# + rust-version = "1.75.0" [features] diff --git a/crates/auto-palette/README.md b/crates/auto-palette/README.md index bbbe5c8..18b1e86 100644 --- a/crates/auto-palette/README.md +++ b/crates/auto-palette/README.md @@ -28,7 +28,7 @@ Using `auto-palette` in your Rust project, add it to your `Cargo.toml`. ```toml [dependencies] -auto-palette = "0.3.0" +auto-palette = "0.4.0" ``` ## Usage @@ -44,7 +44,7 @@ fn main() { let image_data = ImageData::load("../../gfx/holly-booth-hLZWGXy5akM-unsplash.jpg").unwrap(); // Extract the color palette from the image data - let palette: Palette = Palette::extract(&image_data).unwrap(); + let palette: Palette = Palette::extract(&image_data).unwrap(); println!("Extracted {} swatches", palette.len()); // Find the 5 prominent colors in the palette and print their information @@ -57,6 +57,143 @@ fn main() { } ``` +## API + +* [`ImageData`](#imagedata) +* [`Palette`](#palette) +* [`Swatch`](#swatch) + +For more information on the API, see the [documentation](https://docs.rs/auto-palette). + +### `ImageData` + +The `ImageData` struct represents the image data that is used to extract the color palette. + +* [`ImageData::load`](#imagedata-load) +* [`ImageData::new`](#imagedata-new) + + + +#### `ImageData::load` + +Loads the image data from the file. +The supported image formats are `PNG`, `JPEG`, `GIF`, `BMP`, `TIFF`, and `WEBP`. +This method requires the `image` feature to be enabled. The `image` feature is enabled by default. + +```rust +// Load the image data from the file +let image_data = ImageData::load("path/to/image.jpg").unwrap(); +``` + + + +#### `ImageData::new` + +Creates a new instance from the raw image data. +Each pixel is represented by four consecutive bytes in the order of `R`, `G`, `B`, and `A`. + +```rust +// Create a new instance from the raw image data +let pixels = [ + 255, 0, 0, 255, // Red + 0, 255, 0, 255, // Green + 0, 0, 255, 255, // Blue + 255, 255, 0, 255, // Yellow +]; +let image_data = ImageData::new(2, 2, &pixels).unwrap(); +``` + +### `Palette` + +The `Palette` struct represents the color palette extracted from the `ImageData`. + +* [`Palette::extract`](#palette-extract) +* [`Palette::extract_with_algorithm`](#palette-extract-with-algorithm) +* [`Palette::find_swatches`](#palette-find-swatches) +* [`Palette::find_swatches_with_theme`](#palette-find-swatches-with-theme) + + + +#### `Palette::extract` + +Extracts the color palette from the given `ImageData`. +This method is used to extract the color palette with the default `Algorithm`(DBSCAN). + +```rust +// Load the image data from the file +let image_data = ImageData::load("path/to/image.jpg").unwrap(); + +// Extract the color palette from the image data +let palette: Palette = Palette::extract(&image_data).unwrap(); +``` + + + +#### `Palette::extract_with_algorithm` + +Extracts the color palette from the given `ImageData` with the specified `Algorithm`. +The supported algorithms are `DBSCAN`, `DBSCAN++`, and `KMeans++`. + +```rust +// Load the image data from the file +let image_data = ImageData::load("path/to/image.jpg").unwrap(); +// Extract the color palette from the image data with the specified algorithm +let palette: Palette = Palette::extract_with_algorithm(&image_data, Algorithm::DBSCAN).unwrap(); +``` + + + +#### `Palette::find_swatches` + +Finds the prominent colors in the palette based on the number of swatches. +Returned swatches are sorted by their population in descending order. + +```rust +// Find the 5 prominent colors in the palette +let swatches = palette.find_swatches(5); +``` + + + +#### `Palette::find_swatches_with_theme` + +Finds the prominent colors in the palette based on the specified `Theme` and the number of swatches. +The supported themes are `Basic`, `Colorful`, `Vivid`, `Muted`, `Light`, and `Dark`. + +```rust +// Find the 5 prominent colors in the palette with the specified theme +let swatches = palette.find_swatches_with_theme(5, Theme::Light); +``` + +### `Swatch` + +The `Swatch` struct represents the color swatch in the `Palette`. +It contains detailed information about the color, position, population, and ratio. + +```rust +// Find the 5 prominent colors in the palette +let swatches = palette.find_swatches(5); + +for swatch in swatches { + // Get the color, position, and population of the swatch + println!("Color: {:?}", swatch.color()); + println!("Position: {:?}", swatch.position()); + println!("Population: {}", swatch.population()); + println!("Ratio: {}", swatch.ratio()); +} +``` + +> [!TIP] +> The `Color` struct provides various methods to convert the color to different formats, such as `RGB`, `HSL`, and `CIE L*a*b*`. +> ```rust +> let color = swatch.color(); +> println!("Hex: {}", color.to_hex_string()); +> println!("RGB: {:?}", color.to_rgb()); +> println!("HSL: {:?}", color.to_hsl()); +> println!("CIE L*a*b*: {:?}", color.to_lab()); +> println!("Oklch: {:?}", color.to_oklch()); +> ``` + ## Development Follow the instructions below to build and test the project: diff --git a/crates/auto-palette/src/swatch.rs b/crates/auto-palette/src/swatch.rs index d7872f2..cf0172f 100644 --- a/crates/auto-palette/src/swatch.rs +++ b/crates/auto-palette/src/swatch.rs @@ -15,10 +15,11 @@ use crate::{color::Color, math::FloatNumber}; /// }; /// /// let color: Color = Color::from_str("#ff0040").unwrap(); -/// let swatch = Swatch::new(color, (5, 10), 384); +/// let swatch = Swatch::new(color, (5, 10), 384, 0.25); /// assert_eq!(swatch.color().to_rgb(), RGB::new(255, 0, 64)); /// assert_eq!(swatch.position(), (5, 10)); /// assert_eq!(swatch.population(), 384); +/// assert_eq!(swatch.ratio(), 0.25); /// ``` #[derive(Debug, Clone, Copy, PartialEq)] pub struct Swatch @@ -43,7 +44,6 @@ where /// * `population` - The population of the swatch. /// * `ratio` - The ratio of the swatch to the total population. /// - /// /// # Returns /// A new `Swatch` instance. pub fn new(color: Color, position: (u32, u32), population: usize, ratio: T) -> Self {