Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array ToImage conversion methods #15

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
33 changes: 33 additions & 0 deletions src/toimage.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#[cfg(feature = "image")]
mod ndarray_impl;

/// Converts a 2d type to a luma image type.
///
/// This uses an associated type to avoid ambiguity for the compiler.
Expand All @@ -7,3 +10,33 @@ pub trait ToImageLuma {

fn into_image_luma(self) -> Self::Out;
}

/// Converts a 3d array type to an RgbaImage type.
///
/// This uses an associated type to avoid ambiguity for the compiler.
/// By calling this, the compiler always knows the returned type.
pub trait ToImageRgba {
type Out;

fn into_image_rgba(self) -> Self::Out;
}

/// Converts a 3d array type to an RgbaImage type.
///
/// This uses an associated type to avoid ambiguity for the compiler.
/// By calling this, the compiler always knows the returned type.
pub trait ToImageRgb {
type Out;

fn into_image_rgb(self) -> Self::Out;
}

/// Converts a 2d array type to a GrayImage type.
///
/// This uses an associated type to avoid ambiguity for the compiler.
/// By calling this, the compiler always knows the returned type.
pub trait ToImageGray {
type Out;

fn into_image_gray(self) -> Self::Out;
}
70 changes: 70 additions & 0 deletions src/toimage/ndarray_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use super::*;
use image::{GrayImage, ImageBuffer, RgbImage, RgbaImage, };
use ndarray::{Array2, Array3, ArrayView2, ArrayView3, ArrayViewMut2, ArrayViewMut3};

impl ToImageRgba for Array3<u8> {
type Out = RgbaImage;

fn into_image_rgba(self) -> Self::Out {
let (c, h, w) = self.dim();
assert_eq!(c, 4);
let img: RgbaImage =
ImageBuffer::from_raw(w as u32, h as u32, self.into_raw_vec()).unwrap();
img
}
}

impl ToImageRgb for Array3<u8> {
type Out = RgbImage;

fn into_image_rgb(self) -> Self::Out {
let (c, h, w) = self.dim();
assert_eq!(c, 3);
let img: RgbImage = ImageBuffer::from_raw(w as u32, h as u32, self.into_raw_vec()).unwrap();
img
}
}

impl ToImageGray for Array2<u8> {
type Out = GrayImage;

fn into_image_gray(self) -> Self::Out {
let (h, w) = self.dim();
let img: GrayImage =
ImageBuffer::from_raw(w as u32, h as u32, self.into_raw_vec()).unwrap();
img
}
}

mod test {
use image::Rgba;
use crate::ToNdarray3;
use super::*;
use super::ImageBuffer;

#[test]
fn test_img_alpha() {
let img: ImageBuffer<Rgba<u8>, _> = ImageBuffer::from_fn(3, 3, |x, y| {
let value = (y * 3 + x) as u8;
Rgba([value, value, value, 255 - value])
});
let arr = img.into_ndarray3();
assert_eq!(arr.dim(), (4, 3, 3));
let arr_clone = arr.clone();
let img = arr.into_image_rgba();
let (width, height) = img.dimensions();

for y in 0..height {
for x in 0..width {
let arr_pixel = [
arr_clone[[0, y as usize, x as usize]],
arr_clone[[1, y as usize, x as usize]],
arr_clone[[2, y as usize, x as usize]],
arr_clone[[3, y as usize, x as usize]],
];
let img_pixel = img.get_pixel(x, y).0;
assert_eq!(arr_pixel, img_pixel);
}
}
}
}