fast image operations
Diffstat (limited to 'src/scale/mod.rs')
-rw-r--r--src/scale/mod.rs79
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
+ );
+}