diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2020-05-02 13:46:25 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2020-05-03 00:16:33 -0400 |
commit | 5aea448bd2a7f6157cf33a6a2c044d043bbcd3ec (patch) | |
tree | fbd01c8a4d39b19db4314a5f210cdcc2e298f187 | |
parent | 232995aecf809309848b864a77e9d968c6185a29 (diff) | |
download | kd-forest-5aea448bd2a7f6157cf33a6a2c044d043bbcd3ec.tar.xz |
color/source: Implement color sources
-rw-r--r-- | src/color.rs | 2 | ||||
-rw-r--r-- | src/color/source.rs | 76 |
2 files changed, 78 insertions, 0 deletions
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<RgbImage> 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) + } +} |