diff --git a/src/types/geometry_info.rs b/src/types/geometry_info.rs new file mode 100644 index 0000000..f9bee99 --- /dev/null +++ b/src/types/geometry_info.rs @@ -0,0 +1,37 @@ +use crate::bindings; + +pub type GeometryInfo = bindings::GeometryInfo; + +impl GeometryInfo { + pub fn new() -> GeometryInfo { + return GeometryInfo { + rho: 0.0, + sigma: 0.0, + xi: 0.0, + psi: 0.0, + chi: 0.0, + }; + } + + pub fn set_rho(&mut self, rho: f64) { + self.rho = rho; + } + pub fn set_sigma(&mut self, sigma: f64) { + self.sigma = sigma; + } + pub fn set_xi(&mut self, xi: f64) { + self.xi = xi; + } + pub fn set_psi(&mut self, psi: f64) { + self.psi = psi; + } + pub fn set_chi(&mut self, chi: f64) { + self.chi = chi; + } +} + +impl Default for GeometryInfo { + fn default() -> Self { + Self::new() + } +} diff --git a/src/types/kernel.rs b/src/types/kernel.rs index fb8a636..eea766e 100644 --- a/src/types/kernel.rs +++ b/src/types/kernel.rs @@ -106,7 +106,7 @@ impl From for bindings::KernelInfoType { /// Builder, that creates instances of [KernelInfo](self::KernelInfo) /// -/// # Example +/// # Examples /// /// Here is an example of how you can use this struct to create a kernel to convolve an image: /// @@ -132,11 +132,38 @@ impl From for bindings::KernelInfoType { /// Ok(()) /// } /// ``` +/// +/// Here is an example of how you can use this struct to create builtin kernel to gaussian blur an +/// image (not the best way to do it, just an example): +/// +/// ``` +/// use magick_rust::{MagickWand, PixelWand, KernelBuilder, KernelInfoType, GeometryInfo}; +/// +/// 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 +/// let wand2 = wand1.clone(); +/// +/// let mut geom_info = GeometryInfo::new(); +/// geom_info.set_sigma(15.0); +/// let kernel_info = KernelBuilder::new() +/// .set_info_type(KernelInfoType::Gaussian) +/// .set_geom_info(geom_info) +/// .build_builtin()?; +/// +/// wand1.convolve_image(&kernel_info)?; +/// +/// Ok(()) +/// } +/// ``` #[derive(Debug, Clone)] pub struct KernelBuilder { size: Option<(usize, usize)>, center: Option<(usize, usize)>, values: Option>, + + info_type: Option, + geom_info: Option, } impl KernelBuilder { @@ -145,19 +172,25 @@ impl KernelBuilder { size: None, center: None, values: None, + + info_type: None, + geom_info: None, }; } + /// Used for user defined kernels pub fn set_size(mut self, size: (usize, usize)) -> KernelBuilder { self.size = Some(size); return self; } + /// Used for user defined kernels pub fn set_center(mut self, center: (usize, usize)) -> KernelBuilder { self.center = Some(center); return self; } + /// Used for user defined kernels pub fn set_values(mut self, values: &[f64]) -> KernelBuilder { self.values = Some(values.into()); return self; @@ -213,6 +246,38 @@ impl KernelBuilder { Ok(KernelInfo::new(kernel_info)) } + + /// Used for builtin kernels + pub fn set_info_type(mut self, info_type: KernelInfoType) -> KernelBuilder { + self.info_type = Some(info_type); + return self; + } + + /// Used for builtin kernels + pub fn set_geom_info(mut self, geom_info: crate::GeometryInfo) -> KernelBuilder { + self.geom_info = Some(geom_info); + return self; + } + + pub fn build_builtin(&self) -> Result { + let info_type = self.info_type.ok_or(MagickError("no info type given"))?; + let mut geom_info = self.geom_info.ok_or(MagickError("no geometry info given"))?; + + // Create kernel info + let kernel_info = unsafe { + bindings::AcquireKernelBuiltIn( + info_type.into(), + &mut geom_info, + std::ptr::null_mut() + ) + }; + + if kernel_info.is_null() { + return Err(MagickError("failed to acquire builtin kernel info")); + } + + Ok(KernelInfo::new(kernel_info)) + } } pub struct KernelInfo { diff --git a/src/types/mod.rs b/src/types/mod.rs index 50b2d7f..db5a8da 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -13,6 +13,7 @@ mod dither_method; mod endian_type; mod fill_rule; mod filter_type; +mod geometry_info; mod gravity_type; mod image_type; mod interlace_type; @@ -46,6 +47,7 @@ pub use self::dither_method::DitherMethod; pub use self::endian_type::EndianType; pub use self::fill_rule::FillRule; pub use self::filter_type::FilterType; +pub use self::geometry_info::GeometryInfo; pub use self::gravity_type::GravityType; pub use self::image_type::ImageType; pub use self::interlace_type::InterlaceType;