Add a few more functions and typed
Adds `Image` type and a few image related functions.
This commit is contained in:
21
src/types/image.rs
Normal file
21
src/types/image.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::bindings;
|
||||
|
||||
pub struct Image<'a> {
|
||||
image: *mut bindings::Image,
|
||||
phantom_data: PhantomData<&'a bindings::Image>,
|
||||
}
|
||||
|
||||
impl Image<'_> {
|
||||
pub unsafe fn new(img: *mut bindings::Image) -> Self {
|
||||
Image {
|
||||
image: img,
|
||||
phantom_data: PhantomData
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn get_ptr(&self) -> *mut bindings::Image {
|
||||
self.image
|
||||
}
|
||||
}
|
||||
35
src/types/layer_method.rs
Normal file
35
src/types/layer_method.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use crate::bindings;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u32)]
|
||||
pub enum LayerMethod {
|
||||
Undefined = bindings::LayerMethod_UndefinedLayer,
|
||||
Coalesce = bindings::LayerMethod_CoalesceLayer,
|
||||
CompareAny = bindings::LayerMethod_CompareAnyLayer,
|
||||
CompareClear = bindings::LayerMethod_CompareClearLayer,
|
||||
CompareOverlay = bindings::LayerMethod_CompareOverlayLayer,
|
||||
Dispose = bindings::LayerMethod_DisposeLayer,
|
||||
Optimize = bindings::LayerMethod_OptimizeLayer,
|
||||
OptimizeImage = bindings::LayerMethod_OptimizeImageLayer,
|
||||
OptimizePlus = bindings::LayerMethod_OptimizePlusLayer,
|
||||
OptimizeTrans = bindings::LayerMethod_OptimizeTransLayer,
|
||||
RemoveDups = bindings::LayerMethod_RemoveDupsLayer,
|
||||
RemoveZero = bindings::LayerMethod_RemoveZeroLayer,
|
||||
Composite = bindings::LayerMethod_CompositeLayer,
|
||||
Merge = bindings::LayerMethod_MergeLayer,
|
||||
Flatten = bindings::LayerMethod_FlattenLayer,
|
||||
Mosaic = bindings::LayerMethod_MosaicLayer,
|
||||
TrimBounds = bindings::LayerMethod_TrimBoundsLayer,
|
||||
}
|
||||
|
||||
impl Default for LayerMethod {
|
||||
fn default() -> Self {
|
||||
return LayerMethod::Undefined;
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LayerMethod> for bindings::LayerMethod {
|
||||
fn from(value: LayerMethod) -> Self {
|
||||
return value as bindings::LayerMethod;
|
||||
}
|
||||
}
|
||||
@ -15,9 +15,11 @@ mod fill_rule;
|
||||
mod filter_type;
|
||||
mod geometry_info;
|
||||
mod gravity_type;
|
||||
mod image;
|
||||
mod image_type;
|
||||
mod interlace_type;
|
||||
mod kernel;
|
||||
mod layer_method;
|
||||
mod line_cap;
|
||||
mod line_join;
|
||||
mod magick_evaluate_operator;
|
||||
@ -50,9 +52,11 @@ 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::Image;
|
||||
pub use self::image_type::ImageType;
|
||||
pub use self::interlace_type::InterlaceType;
|
||||
pub use self::kernel::*;
|
||||
pub use self::layer_method::LayerMethod;
|
||||
pub use self::line_cap::LineCap;
|
||||
pub use self::line_join::LineJoin;
|
||||
pub use self::magick_evaluate_operator::MagickEvaluateOperator;
|
||||
|
||||
@ -42,9 +42,11 @@ use crate::{
|
||||
EndianType,
|
||||
FilterType,
|
||||
GravityType,
|
||||
Image,
|
||||
ImageType,
|
||||
InterlaceType,
|
||||
KernelInfo,
|
||||
LayerMethod,
|
||||
MagickEvaluateOperator,
|
||||
MagickFunction,
|
||||
MetricType,
|
||||
@ -77,6 +79,21 @@ wand_common!(
|
||||
/// When the `MagickWand` is dropped, the ImageMagick wand will be
|
||||
/// destroyed as well.
|
||||
impl MagickWand {
|
||||
/// Creates new wand by cloning the image.
|
||||
///
|
||||
/// * `img`: the image.
|
||||
pub fn new_from_image(img: &Image<'_>) -> Result<MagickWand> {
|
||||
let result = unsafe {
|
||||
bindings::NewMagickWandFromImage(img.get_ptr())
|
||||
};
|
||||
|
||||
return if result.is_null() {
|
||||
Err(MagickError("failed to create wand from image"))
|
||||
} else {
|
||||
Ok(MagickWand { wand: result })
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_image(&self, columns: usize, rows: usize, background: &PixelWand) -> Result<()> {
|
||||
match unsafe { bindings::MagickNewImage(self.wand, columns.into(), rows.into(), background.wand) } {
|
||||
MagickTrue => Ok(()),
|
||||
@ -224,6 +241,37 @@ impl MagickWand {
|
||||
}
|
||||
}
|
||||
|
||||
/// Composes all the image layers from the current given image onward to produce a single image
|
||||
/// of the merged layers.
|
||||
///
|
||||
/// The inital canvas's size depends on the given LayerMethod, and is initialized using the
|
||||
/// first images background color. The images are then composited onto that image in sequence
|
||||
/// using the given composition that has been assigned to each individual image.
|
||||
///
|
||||
/// * `method`: the method of selecting the size of the initial canvas.
|
||||
/// MergeLayer: Merge all layers onto a canvas just large enough to hold all the actual
|
||||
/// images. The virtual canvas of the first image is preserved but otherwise ignored.
|
||||
///
|
||||
/// FlattenLayer: Use the virtual canvas size of first image. Images which fall outside
|
||||
/// this canvas is clipped. This can be used to 'fill out' a given virtual canvas.
|
||||
///
|
||||
/// MosaicLayer: Start with the virtual canvas of the first image, enlarging left and right
|
||||
/// edges to contain all images. Images with negative offsets will be clipped.
|
||||
pub fn merge_image_layers(&self, method: LayerMethod) -> Result<MagickWand> {
|
||||
let result = unsafe {
|
||||
bindings::MagickMergeImageLayers(self.wand, method.into())
|
||||
};
|
||||
if result.is_null() {
|
||||
return Err(MagickError("failed to merge image layres"));
|
||||
}
|
||||
return Ok(MagickWand { wand: result });
|
||||
}
|
||||
|
||||
/// Returns the number of images associated with a magick wand.
|
||||
pub fn get_number_images(&self) -> usize {
|
||||
return unsafe { bindings::MagickGetNumberImages(self.wand).into() };
|
||||
}
|
||||
|
||||
/// Compare two images and return tuple `(distortion, diffImage)`
|
||||
/// `diffImage` is `None` if `distortion == 0`
|
||||
pub fn compare_images(
|
||||
@ -1540,6 +1588,64 @@ impl MagickWand {
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies a channel expression to the specified image. The expression
|
||||
/// consists of one or more channels, either mnemonic or numeric (e.g. red, 1), separated by
|
||||
/// actions as follows:
|
||||
///
|
||||
/// <=> exchange two channels (e.g. red<=>blue) => transfer a channel to another (e.g.
|
||||
/// red=>green) , separate channel operations (e.g. red, green) | read channels from next input
|
||||
/// image (e.g. red | green) ; write channels to next output image (e.g. red; green; blue) A
|
||||
/// channel without a operation symbol implies extract. For example, to create 3 grayscale
|
||||
/// images from the red, green, and blue channels of an image, use:
|
||||
///
|
||||
/// * `expression`: the expression.
|
||||
pub fn channel_fx_image(&self, expression: &str) -> Result<MagickWand> {
|
||||
let c_expression = CString::new(expression).map_err(|_| MagickError("artifact string contains null byte"))?;
|
||||
|
||||
let result = unsafe {
|
||||
bindings::MagickChannelFxImage(
|
||||
self.wand,
|
||||
c_expression.as_ptr()
|
||||
)
|
||||
};
|
||||
|
||||
return if result.is_null() {
|
||||
Err(MagickError("failed to apply expression to image"))
|
||||
} else {
|
||||
Ok(MagickWand{ wand: result })
|
||||
};
|
||||
}
|
||||
|
||||
/// Combines one or more images into a single image. The grayscale value of the pixels of each
|
||||
/// image in the sequence is assigned in order to the specified channels of the combined image.
|
||||
/// The typical ordering would be image 1 => Red, 2 => Green, 3 => Blue, etc.
|
||||
///
|
||||
/// * `colorspace`: the colorspace.
|
||||
pub fn combine_images(&self, colorspace: ColorspaceType) -> Result<MagickWand> {
|
||||
let result = unsafe {
|
||||
bindings::MagickCombineImages(self.wand, colorspace.into())
|
||||
};
|
||||
|
||||
return if result.is_null() {
|
||||
Err(MagickError("failed to combine images"))
|
||||
} else {
|
||||
Ok(MagickWand{ wand: result })
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the current image from the magick wand.
|
||||
pub fn get_image<'wand>(&'wand self) -> Result<Image<'wand>> {
|
||||
let result = unsafe {
|
||||
bindings::GetImageFromMagickWand(self.wand)
|
||||
};
|
||||
|
||||
return if result.is_null() {
|
||||
Err(MagickError("no image in wand"))
|
||||
} else {
|
||||
unsafe { Ok(Image::new(result)) }
|
||||
}
|
||||
}
|
||||
|
||||
mutations!(
|
||||
/// Sets the image to the specified alpha level.
|
||||
MagickSetImageAlpha => set_image_alpha(alpha: f64)
|
||||
|
||||
Reference in New Issue
Block a user