From 5aea448bd2a7f6157cf33a6a2c044d043bbcd3ec Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 2 May 2020 13:46:25 -0400 Subject: color/source: Implement color sources --- src/color.rs | 2 ++ src/color/source.rs | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 src/color/source.rs diff --git a/src/color.rs b/src/color.rs index a062795..e0a3399 100644 --- a/src/color.rs +++ b/src/color.rs @@ -1,5 +1,7 @@ //! Colors and color spaces. +pub mod source; + use crate::metric::kd::{Cartesian, CartesianMetric}; use crate::metric::{Metric, SquaredDistance}; diff --git a/src/color/source.rs b/src/color/source.rs new file mode 100644 index 0000000..bd752d9 --- /dev/null +++ b/src/color/source.rs @@ -0,0 +1,76 @@ +//! Sources of colors. + +use super::Rgb8; + +use image::RgbImage; + +/// A source of colors in multidimensional space. +pub trait ColorSource { + /// Get the size of each dimension in this space. + fn dimensions(&self) -> &[usize]; + + /// Get the color at some particular coordinates. + fn get_color(&self, coords: &[usize]) -> Rgb8; +} + +/// The entire RGB space. +#[derive(Debug)] +pub struct AllColors { + dims: [usize; 3], + shifts: [usize; 3], +} + +impl AllColors { + /// Create an AllColors source with the given bit depth. + pub fn new(bits: usize) -> Self { + // Allocate bits from most to least perceptually important + let gbits = (bits + 2) / 3; + let rbits = (bits + 1) / 3; + let bbits = bits / 3; + + Self { + dims: [1 << rbits, 1 << gbits, 1 << bbits], + shifts: [8 - rbits, 8 - gbits, 8 - bbits], + } + } +} + +impl ColorSource for AllColors { + fn dimensions(&self) -> &[usize] { + &self.dims + } + + fn get_color(&self, coords: &[usize]) -> Rgb8 { + Rgb8::from([ + (coords[0] << self.shifts[0]) as u8, + (coords[1] << self.shifts[1]) as u8, + (coords[2] << self.shifts[2]) as u8, + ]) + } +} + +/// Colors extracted from an image. +#[derive(Debug)] +pub struct ImageColors { + dims: [usize; 2], + image: RgbImage, +} + +impl From for ImageColors { + fn from(image: RgbImage) -> Self { + Self { + dims: [image.width() as usize, image.height() as usize], + image: image, + } + } +} + +impl ColorSource for ImageColors { + fn dimensions(&self) -> &[usize] { + &self.dims + } + + fn get_color(&self, coords: &[usize]) -> Rgb8 { + *self.image.get_pixel(coords[0] as u32, coords[1] as u32) + } +} -- cgit v1.2.3