Skip to content

Commit

Permalink
Merge pull request #1596 from ForgottenMaster/issue-1466
Browse files Browse the repository at this point in the history
Issue 1466
  • Loading branch information
HeroicKatora authored Nov 1, 2021
2 parents fa82b5e + 7f755d8 commit ceabd67
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 13 deletions.
75 changes: 70 additions & 5 deletions src/dynimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,15 +588,15 @@ impl DynamicImage {
pub fn grayscale(&self) -> DynamicImage {
match *self {
DynamicImage::ImageLuma8(ref p) => DynamicImage::ImageLuma8(p.clone()),
DynamicImage::ImageLumaA8(ref p) => DynamicImage::ImageLuma8(imageops::grayscale(p)),
DynamicImage::ImageLumaA8(ref p) => DynamicImage::ImageLumaA8(imageops::grayscale_alpha(p)),
DynamicImage::ImageRgb8(ref p) => DynamicImage::ImageLuma8(imageops::grayscale(p)),
DynamicImage::ImageRgba8(ref p) => DynamicImage::ImageLuma8(imageops::grayscale(p)),
DynamicImage::ImageRgba8(ref p) => DynamicImage::ImageLumaA8(imageops::grayscale_alpha(p)),
DynamicImage::ImageLuma16(ref p) => DynamicImage::ImageLuma16(p.clone()),
DynamicImage::ImageLumaA16(ref p) => DynamicImage::ImageLuma16(imageops::grayscale(p)),
DynamicImage::ImageLumaA16(ref p) => DynamicImage::ImageLumaA16(imageops::grayscale_alpha(p)),
DynamicImage::ImageRgb16(ref p) => DynamicImage::ImageLuma16(imageops::grayscale(p)),
DynamicImage::ImageRgba16(ref p) => DynamicImage::ImageLuma16(imageops::grayscale(p)),
DynamicImage::ImageRgba16(ref p) => DynamicImage::ImageLumaA16(imageops::grayscale_alpha(p)),
DynamicImage::ImageRgb32F(ref p) => DynamicImage::ImageRgb32F(imageops::grayscale_with_type(p)),
DynamicImage::ImageRgba32F(ref p) => DynamicImage::ImageRgba32F(imageops::grayscale_with_type(p)),
DynamicImage::ImageRgba32F(ref p) => DynamicImage::ImageRgba32F(imageops::grayscale_with_type_alpha(p)),
}
}

Expand Down Expand Up @@ -1198,4 +1198,69 @@ mod test {
let image = super::open(im_path).unwrap();
assert_eq!(image.color(), super::color::ColorType::Rgba16);
}

fn test_grayscale(mut img: super::DynamicImage, alpha_discarded: bool) {
use crate::image::{GenericImage, GenericImageView};
img.put_pixel(0, 0, crate::color::Rgba([255, 0, 0, 100]));
let expected_alpha = if alpha_discarded { 255 } else { 100 };
assert_eq!(img.grayscale().get_pixel(0, 0), crate::color::Rgba([54, 54, 54, expected_alpha]));
}

fn test_grayscale_alpha_discarded(img: super::DynamicImage) {
test_grayscale(img, true);
}

fn test_grayscale_alpha_preserved(img: super::DynamicImage) {
test_grayscale(img, false);
}

#[test]
fn test_grayscale_luma8() {
test_grayscale_alpha_discarded(super::DynamicImage::new_luma8(1, 1));
}

#[test]
fn test_grayscale_luma_a8() {
test_grayscale_alpha_preserved(super::DynamicImage::new_luma_a8(1, 1));
}

#[test]
fn test_grayscale_rgb8() {
test_grayscale_alpha_discarded(super::DynamicImage::new_rgb8(1, 1));
}

#[test]
fn test_grayscale_rgba8() {
test_grayscale_alpha_preserved(super::DynamicImage::new_rgba8(1, 1));
}

#[test]
fn test_grayscale_luma16() {
test_grayscale_alpha_discarded(super::DynamicImage::new_luma16(1, 1));
}

#[test]
fn test_grayscale_luma_a16() {
test_grayscale_alpha_preserved(super::DynamicImage::new_luma_a16(1, 1));
}

#[test]
fn test_grayscale_rgb16() {
test_grayscale_alpha_discarded(super::DynamicImage::new_rgb16(1, 1));
}

#[test]
fn test_grayscale_rgba16() {
test_grayscale_alpha_preserved(super::DynamicImage::new_rgba16(1, 1));
}

#[test]
fn test_grayscale_rgb32f() {
test_grayscale_alpha_discarded(super::DynamicImage::new_rgb32f(1, 1));
}

#[test]
fn test_grayscale_rgba32f() {
test_grayscale_alpha_preserved(super::DynamicImage::new_rgba32f(1, 1));
}
}
35 changes: 28 additions & 7 deletions src/imageops/colorops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use num_traits::{Num, NumCast};
use std::f64::consts::PI;

use crate::color::{Luma, Rgba, FromColor, IntoColor};
use crate::color::{Luma, LumaA, Rgba, FromColor, IntoColor};
use crate::image::{GenericImage, GenericImageView};
use crate::traits::{Pixel, Primitive};
use crate::utils::clamp;
Expand All @@ -13,19 +13,20 @@ type Subpixel<I> = <<I as GenericImageView>::Pixel as Pixel>::Subpixel;

/// Convert the supplied image to grayscale. Alpha channel is discarded.
pub fn grayscale<I: GenericImageView>(image: &I) -> ImageBuffer<Luma<Subpixel<I>>, Vec<Subpixel<I>>>
where
Subpixel<I>: 'static,
<Subpixel<I> as Num>::FromStrRadixErr: 'static,
{
grayscale_with_type(image)
}

/// Convert the supplied image to grayscale. Alpha channel is preserved.
pub fn grayscale_alpha<I: GenericImageView>(image: &I) -> ImageBuffer<LumaA<Subpixel<I>>, Vec<Subpixel<I>>>
{
grayscale_with_type_alpha(image)
}

/// Convert the supplied image to a grayscale image with the specified pixel type. Alpha channel is discarded.
pub fn grayscale_with_type<NewPixel, I: GenericImageView>(image: &I) -> ImageBuffer<NewPixel, Vec<NewPixel::Subpixel>>
where
Subpixel<I>: 'static,
<Subpixel<I> as Num>::FromStrRadixErr: 'static,
NewPixel: 'static + Pixel + FromColor<Luma<Subpixel<I>>>
NewPixel: Pixel + FromColor<Luma<Subpixel<I>>>
{
let (width, height) = image.dimensions();
let mut out = ImageBuffer::new(width, height);
Expand All @@ -42,6 +43,26 @@ where
out
}

/// Convert the supplied image to a grayscale image with the specified pixel type. Alpha channel is preserved.
pub fn grayscale_with_type_alpha<NewPixel, I: GenericImageView>(image: &I) -> ImageBuffer<NewPixel, Vec<NewPixel::Subpixel>>
where
NewPixel: Pixel + FromColor<LumaA<Subpixel<I>>>
{
let (width, height) = image.dimensions();
let mut out = ImageBuffer::new(width, height);

for y in 0..height {
for x in 0..width {
let grayscale = image.get_pixel(x, y).to_luma_alpha();
let pixel = grayscale.into_color(); // no-op for luma->luma

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

out
}

/// Invert each pixel within the supplied image.
/// This function operates in place.
pub fn invert<I: GenericImage>(image: &mut I) {
Expand Down
2 changes: 1 addition & 1 deletion src/imageops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub use self::affine::{
pub use self::sample::{blur, filter3x3, resize, thumbnail, unsharpen};

/// Color operations
pub use self::colorops::{brighten, contrast, dither, grayscale, grayscale_with_type, huerotate, index_colors, invert,
pub use self::colorops::{brighten, contrast, dither, grayscale, grayscale_alpha, grayscale_with_type, grayscale_with_type_alpha, huerotate, index_colors, invert,
BiLevel, ColorMap};

mod affine;
Expand Down

0 comments on commit ceabd67

Please sign in to comment.