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
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);
}
}
}
}