Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/dynimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,9 +736,21 @@ impl DynamicImage {
}

/// Invert the colors of this image.
/// This method operates inplace.
/// use [DynamicImage::invert_in_place()] for an in-place version.
pub fn invert_to(&self) -> DynamicImage {
dynamic_map!(*self, ref p => imageops::invert_to(p))
}

/// Invert the colors of this image.
/// Use [`DynamicImage::invert_in_place()`] directly instead of this function
pub fn invert(&mut self) {
dynamic_map!(*self, ref mut p, imageops::invert(p));
self.invert_in_place();
}

/// Invert the colors of this image.
/// This method operates inplace.
pub fn invert_in_place(&mut self) {
dynamic_map!(*self, ref mut p, imageops::invert_in_place(p));
}

/// Resize this image using the specified filter algorithm.
Expand Down
59 changes: 58 additions & 1 deletion src/imageops/colorops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,40 @@ where
}

/// Invert each pixel within the supplied image.
/// This function operates in place.
/// Use [`invert_in_place`] directly instead of this function
/// See also [`invert_to`].
pub fn invert<I: GenericImage>(image: &mut I) {
invert_in_place(image)
}

/// Invert each pixel within the supplied image.
/// See also [`invert_in_place`] for an in-place version.
pub fn invert_to<I: GenericImage>(
image: &I,
) -> ImageBuffer<I::Pixel, Vec<<I::Pixel as Pixel>::Subpixel>>
where
I::Pixel: 'static,
{
// TODO find a way to use pixels?
let (width, height) = image.dimensions();

let mut out = ImageBuffer::new(width, height);
let (width, height) = image.dimensions();
for y in 0..height {
for x in 0..width {
let mut p = image.get_pixel(x, y);
p.invert();

out.put_pixel(x, y, p);
}
}
out
}

/// Invert an image vertically in place.
/// See also [`invert_to`] for a non-in-place version.
pub fn invert_in_place<I: GenericImage>(image: &mut I) {
let (width, height) = image.dimensions();
for y in 0..height {
for x in 0..width {
let mut p = image.get_pixel(x, y);
Expand Down Expand Up @@ -599,6 +628,22 @@ mod test {
assert_pixels_eq!(&grayscale(&image), &expected);
}

#[test]
fn test_invert_to() {
let base_image: GrayImage =
ImageBuffer::from_raw(3, 2, vec![0u8, 1u8, 2u8, 10u8, 11u8, 12u8]).unwrap();

let image: GrayImage = base_image.clone();

let expected: GrayImage =
ImageBuffer::from_raw(3, 2, vec![255u8, 254u8, 253u8, 245u8, 244u8, 243u8]).unwrap();

let image_out = invert_to(&image);
assert_pixels_eq!(&image_out, &expected);
// assert the original image is unchanged
assert_pixels_eq!(&image, &base_image);
}

#[test]
fn test_invert() {
let mut image: GrayImage =
Expand All @@ -610,6 +655,18 @@ mod test {
invert(&mut image);
assert_pixels_eq!(&image, &expected);
}

#[test]
fn test_invert_in_place() {
let mut image: GrayImage =
ImageBuffer::from_raw(3, 2, vec![0u8, 1u8, 2u8, 10u8, 11u8, 12u8]).unwrap();

let expected: GrayImage =
ImageBuffer::from_raw(3, 2, vec![255u8, 254u8, 253u8, 245u8, 244u8, 243u8]).unwrap();

invert_in_place(&mut image);
assert_pixels_eq!(&image, &expected);
}
#[test]
fn test_brighten() {
let image: GrayImage =
Expand Down
3 changes: 2 additions & 1 deletion src/imageops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ pub use self::sample::{
/// Color operations
pub use self::colorops::{
brighten, contrast, dither, grayscale, grayscale_alpha, grayscale_with_type,
grayscale_with_type_alpha, huerotate, index_colors, invert, BiLevel, ColorMap,
grayscale_with_type_alpha, huerotate, index_colors, invert_in_place, invert, invert_to, BiLevel,
ColorMap,
};

mod affine;
Expand Down
Loading