fast image operations
Diffstat (limited to 'src/scale/mod.rs')
| -rw-r--r-- | src/scale/mod.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/scale/mod.rs b/src/scale/mod.rs new file mode 100644 index 0000000..ca68970 --- /dev/null +++ b/src/scale/mod.rs @@ -0,0 +1,79 @@ +//! holds scaling operations. +//! +//! choose from the wide expanse of options (ordered fastest to slowest): +//! +//! - [`Nearest`]: quickest, dumbest, jaggedest, scaling algorithm +//! - [`Box`]: you want slightly less pixels than nearest? here you go! kinda blurry though. +//! - [`Bilinear`]: _smooth_ scaling algorithm. rather fuzzy. +//! - [`Hamming`]: solves the [`Box`] problems. clearer image. +//! - [`CatmullRom`]: about the same as [`Hamming`], just a little slower. +//! - [`Mitchell`]: honestly, cant see the difference from [`CatmullRom`]. +//! - [`Lanczos3`]: prettiest scaling algorithm. highly recommend. +//! +//! usage: +//! ``` +//! # use fimg::{Image, scale::Lanczos3}; +//! let i = Image::<_, 3>::open("tdata/small_cat.png"); +//! let scaled = i.scale::<Lanczos3>(2144, 1424); +//! ``` +use crate::Image; + +mod algorithms; +pub mod traits; +pub use algorithms::*; + +macro_rules! transparent { + ($n: literal, $name: ident) => { + impl<T: AsMut<[u8]> + AsRef<[u8]>> Image<T, $n> { + /// Scale a + #[doc = stringify!($name)] + /// image with a given scaling algorithm. + pub fn scale<A: traits::ScalingAlgorithm>( + &mut self, + width: u32, + height: u32, + ) -> Image<std::boxed::Box<[u8]>, $n> { + A::scale_transparent( + self.as_mut(), + width.try_into().unwrap(), + height.try_into().unwrap(), + ) + } + } + }; +} + +macro_rules! opaque { + ($n: literal, $name: ident) => { + impl<T: AsMut<[u8]> + AsRef<[u8]>> Image<T, $n> { + /// Scale a + #[doc = stringify!($name)] + /// image with a given scaling algorithm. + pub fn scale<A: traits::ScalingAlgorithm>( + &self, + width: u32, + height: u32, + ) -> Image<std::boxed::Box<[u8]>, $n> { + A::scale_opaque( + self.as_ref(), + width.try_into().unwrap(), + height.try_into().unwrap(), + ) + } + } + }; +} + +opaque!(1, Y); +transparent!(2, YA); +opaque!(3, RGB); +transparent!(4, RGBA); + +#[test] +fn test_nearest() { + let i = Image::<_, 3>::open("tdata/cat.png"); + assert_eq!( + &*i.scale::<Nearest>(268, 178).buffer, + &*Image::<_, 3>::open("tdata/small_cat.png").buffer + ); +} |