From 5eb991ba695f73e9021dfb613b1f1e14bf46079b Mon Sep 17 00:00:00 2001 From: 5ohue <86558263+5ohue@users.noreply.github.com> Date: Sat, 11 May 2024 23:30:41 +0300 Subject: [PATCH] Add `function_image`, `polynomial_image` functions --- src/types/magick_function.rs | 23 ++++++++++++ src/types/mod.rs | 2 ++ src/wand/magick.rs | 68 +++++++++++++++++++++++++++++++++++- 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/types/magick_function.rs diff --git a/src/types/magick_function.rs b/src/types/magick_function.rs new file mode 100644 index 0000000..ee68042 --- /dev/null +++ b/src/types/magick_function.rs @@ -0,0 +1,23 @@ +use crate::bindings; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u32)] +pub enum MagickFunction { + Undefined = bindings::MagickFunction_UndefinedFunction, + Arcsin = bindings::MagickFunction_ArcsinFunction, + Arctan = bindings::MagickFunction_ArctanFunction, + Polynomial = bindings::MagickFunction_PolynomialFunction, + Sinusoid = bindings::MagickFunction_SinusoidFunction, +} + +impl Default for MagickFunction { + fn default() -> Self { + return MagickFunction::Undefined; + } +} + +impl From for bindings::MagickFunction { + fn from(value: MagickFunction) -> Self { + return value as bindings::MagickFunction; + } +} diff --git a/src/types/mod.rs b/src/types/mod.rs index 762c77a..496bcef 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -16,6 +16,7 @@ mod image_type; mod interlace_type; mod line_cap; mod line_join; +mod magick_function; mod metric_type; mod orientation_type; mod pixel_interpolate_method; @@ -44,6 +45,7 @@ pub use self::image_type::ImageType; pub use self::interlace_type::InterlaceType; pub use self::line_cap::LineCap; pub use self::line_join::LineJoin; +pub use self::magick_function::MagickFunction; pub use self::metric_type::MetricType; pub use self::orientation_type::OrientationType; pub use self::pixel_interpolate_method::PixelInterpolateMethod; diff --git a/src/wand/magick.rs b/src/wand/magick.rs index 8937994..085a8d9 100644 --- a/src/wand/magick.rs +++ b/src/wand/magick.rs @@ -42,6 +42,7 @@ use crate::{ GravityType, ImageType, InterlaceType, + MagickFunction, MetricType, OrientationType, PixelInterpolateMethod, @@ -698,7 +699,7 @@ impl MagickWand { /// /// fn main() -> Result<(), magick_rust::MagickError> { /// let mut wand1 = MagickWand::new(); - /// wand1.new_image(4, 4, &PixelWand::new())?; + /// wand1.new_image(4, 4, &PixelWand::new())?; // Replace with `read_image` to open your image file /// let wand2 = wand1.clone(); /// /// wand1.median_blur_image(10, 10)?; @@ -1341,6 +1342,71 @@ impl MagickWand { } } + /// Applies an arithmetic, relational, or logical expression to an image. Use these operators + /// to lighten or darken an image, to increase or decrease contrast in an image, or to produce + /// the "negative" of an image. + /// + /// * `function`: the image function. + /// * `args`: the function arguments. + /// + /// # Example + /// + /// This example show how you can apply smoothstep function (a polynomial `-2x^3 + 3x^2`) to + /// every image pixel. + /// + /// ``` + /// use magick_rust::{MagickWand, PixelWand, MagickFunction}; + /// + /// fn main() -> Result<(), magick_rust::MagickError> { + /// let mut wand1 = MagickWand::new(); + /// wand1.new_image(4, 4, &PixelWand::new())?; // Replace with `read_image` to open your image file + /// + /// // Apply smoothstep polynomial + /// wand1.function_image(MagickFunction::Polynomial, &[-2.0, 3.0, 0.0, 0.0])?; + /// + /// Ok(()) + /// } + /// ``` + pub fn function_image( + &self, + function: MagickFunction, + args: &[f64] + ) -> Result<()> { + let num_of_args: size_t = args.len().into(); + match unsafe { + bindings::MagickFunctionImage( + self.wand, + function.into(), + num_of_args, + args.as_ptr() + ) + } { + MagickTrue => Ok(()), + _ => Err(MagickError("failed to apply function to image")), + } + } + + /// Returns an image where each pixel is the sum of the pixels in the image sequence after + /// applying its corresponding terms (coefficient and degree pairs). + /// + /// * `terms`: the list of polynomial coefficients and degree pairs and a constant. + pub fn polynomial_image(&self, terms: &[f64]) -> Result<()> { + if terms.len() & 1 != 1 { + return Err(MagickError("no constant coefficient given")); + } + let num_of_terms: size_t = (terms.len() >> 1).into(); + match unsafe { + bindings::MagickPolynomialImage( + self.wand, + num_of_terms, + terms.as_ptr() + ) + } { + MagickTrue => Ok(()), + _ => Err(MagickError("failed to apply polynomial to image")), + } + } + mutations!( /// Sets the image to the specified alpha level. MagickSetImageAlpha => set_image_alpha(alpha: f64)