From bdcd67a3c53fb969af262913d25c43e85e8b35df Mon Sep 17 00:00:00 2001 From: arabian Date: Tue, 6 Jan 2026 06:35:35 +0300 Subject: [PATCH] add docs --- src/lib.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index ab761bf..8585cdd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,11 @@ use std::{ fmt::{Display, Formatter, Result as fmtResult}, }; +/// Represents a color in the HSL (Hue, Saturation, Lightness) color space. +/// +/// Note: In this implementation, values are stored as `u8` (0-255) rather than +/// the standard degrees (0-360) and percentages (0-100), following the +/// integer-based logic inherited from `colorgram.py`. #[derive(PartialEq, Eq, Debug)] pub struct Hsl { pub h: u8, @@ -17,6 +22,7 @@ impl Display for Hsl { } } +/// Represents a color in the RGB (Red, Green, Blue) color space. #[derive(PartialEq, Eq, Debug)] pub struct Rgb { pub r: u8, @@ -30,14 +36,24 @@ impl Display for Rgb { } } +/// A structure representing an extracted color, its HSL equivalent, +/// and its prevalence in the image. #[derive(PartialEq, Debug)] pub struct Color { + /// The average RGB color of the cluster. pub rgb: Rgb, + /// The HSL representation (calculated using the bug-compatible `rgb_to_hsl`). pub hsl: Hsl, + /// The proportion of this color in the image (range 0.0 to 1.0). pub proportion: f32, } impl Color { + /// Creates a new `Color` instance and automatically calculates its HSL value. + /// + /// ### Arguments: + /// * `rgb` - The base RGB color. + /// * `proportion` - The weight of this color relative to others. pub fn new(rgb: Rgb, proportion: f32) -> Color { let hsl = rgb_to_hsl(&rgb); Color { @@ -48,6 +64,25 @@ impl Color { } } +/// Converts RGB color space to HSL. +/// +/// ### ⚠️ Bug-compatibility Warning: +/// This function **does not** produce a mathematically correct HSL value. It contains +/// specific calculation errors inherited from the original `colorgram.py` library. +/// These deviations are preserved intentionally to ensure that the color extraction +/// results remain identical to the Python implementation. +/// +/// ### Implementation Details: +/// * **Luminance (L)**: Calculated as the average of the most and least dominant components. +/// * **Saturation (S)**: Scaled to 0-255 range using integer division that may lose precision. +/// * **Hue (H)**: Calculated using a 0-255 scale (instead of 0-360°) with custom offsets +/// (1530, 510, 1020) and integer math. +/// +/// ### Arguments: +/// * `rgb` - A reference to the input `Rgb` struct. +/// +/// ### Returns: +/// * `Hsl` - The "colorgram-style" HSL representation. fn rgb_to_hsl(rgb: &Rgb) -> Hsl { let r = rgb.r as i32; let g = rgb.g as i32; @@ -80,6 +115,35 @@ fn rgb_to_hsl(rgb: &Rgb) -> Hsl { Hsl { h, s, l: l as u8 } } +/// Extracts a palette of dominant colors from an image buffer. +/// +/// ### Process: +/// 1. **Decoding**: Loads the image from the provided byte buffer and converts it to RGB8. +/// 2. **Quantization**: Pixels are grouped into "buckets" based on a simplified 6-bit key +/// derived from Luminance (Y), Hue (H), and Lightness (L). +/// 3. **Aggregation**: Sums the R, G, and B components and counts pixels in each bucket. +/// 4. **Averaging**: Calculates the mean color for each non-empty bucket. +/// 5. **Selection**: Returns the top `number_of_color` most frequent colors. +/// +/// ### Arguments: +/// * `buffer` - A byte slice containing encoded image data (e.g., JPEG, PNG). +/// * `number_of_color` - The maximum number of dominant colors to return. +/// +/// ### Example: +/// ```rust +/// use colorgram::{extract, Color}; +/// use std::fs; +/// +/// fn main() -> Result<(), Box> { +/// let buf = fs::read("image.jpg")?; +/// let colors = extract(&buf, 5)?; +/// +/// for color in colors { +/// println!("Color: {}, Weight: {:.2}%", color.rgb, color.proportion * 100.0); +/// } +/// Ok(()) +/// } +/// ``` pub fn extract(buffer: &[u8], number_of_color: usize) -> Result, Box> { let img = image::load_from_memory(buffer)?; let img = img.to_rgb8();