mirror of
https://github.com/Cykooz/fast_image_resize.git
synced 2026-10-07 17:01:09 +00:00
Added support of some variants of ImageBuffer types form the image crate (#57).
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
## [Unreleased] - ReleaseDate
|
||||
|
||||
### Added
|
||||
|
||||
- Added support of some variants of `ImageBuffer` types
|
||||
form the `image` crate ([#57](https://github.com/Cykooz/fast_image_resize/issues/57)).
|
||||
|
||||
## [5.4.0] - 2025-11-28
|
||||
|
||||
### Added
|
||||
|
||||
@@ -34,6 +34,8 @@ rayon = { version = "1.11", optional = true }
|
||||
## Enable this feature to implement traits [IntoImageView](crate::IntoImageView) and
|
||||
## [IntoImageViewMut](crate::IntoImageViewMut) for the
|
||||
## [DynamicImage](https://docs.rs/image/latest/image/enum.DynamicImage.html)
|
||||
## type and some variants of
|
||||
## [ImageBuffer](https://docs.rs/image/latest/image/struct.ImageBuffer.html)
|
||||
## type from the `image` crate.
|
||||
image = ["dep:image", "dep:bytemuck"]
|
||||
## Enable this feature to implement traits [bytemuck::Pod] and
|
||||
@@ -191,6 +193,7 @@ harness = false
|
||||
[[bench]]
|
||||
name = "bench_threads"
|
||||
harness = false
|
||||
required-features = ["rayon"]
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,10 @@ use crate::image_view::try_pixel_type;
|
||||
use crate::images::{TypedImage, TypedImageRef};
|
||||
use crate::{ImageView, ImageViewMut, IntoImageView, IntoImageViewMut, PixelTrait, PixelType};
|
||||
use bytemuck::cast_slice_mut;
|
||||
use image::DynamicImage;
|
||||
use image::{
|
||||
DynamicImage, GrayAlphaImage, GrayImage, ImageBuffer, Luma, LumaA, Rgb, Rgb32FImage, RgbImage,
|
||||
Rgba, Rgba32FImage, RgbaImage,
|
||||
};
|
||||
|
||||
impl IntoImageView for DynamicImage {
|
||||
fn pixel_type(&self) -> Option<PixelType> {
|
||||
@@ -77,3 +80,66 @@ fn image_as_bytes_mut(image: &mut DynamicImage) -> &mut [u8] {
|
||||
_ => &mut [],
|
||||
}
|
||||
}
|
||||
|
||||
// Implementations for supported versions of ImageBuffer
|
||||
|
||||
macro_rules! impl_for_img_buffer {
|
||||
($img_type:tt, $pixel_type:expr) => {
|
||||
impl IntoImageView for $img_type {
|
||||
fn pixel_type(&self) -> Option<PixelType> {
|
||||
Some($pixel_type)
|
||||
}
|
||||
|
||||
fn width(&self) -> u32 {
|
||||
self.width()
|
||||
}
|
||||
|
||||
fn height(&self) -> u32 {
|
||||
self.height()
|
||||
}
|
||||
|
||||
fn image_view<P: PixelTrait>(&self) -> Option<impl ImageView<Pixel = P>> {
|
||||
if P::pixel_type() == $pixel_type {
|
||||
let bytes = bytemuck::cast_slice(self.as_raw().as_ref());
|
||||
return TypedImageRef::<P>::from_buffer(self.width(), self.height(), bytes)
|
||||
.ok();
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoImageViewMut for $img_type {
|
||||
fn image_view_mut<P: PixelTrait>(&mut self) -> Option<impl ImageViewMut<Pixel = P>> {
|
||||
if P::pixel_type() == $pixel_type {
|
||||
return TypedImage::<P>::from_buffer(
|
||||
self.width(),
|
||||
self.height(),
|
||||
cast_slice_mut((*self).deref_mut()),
|
||||
)
|
||||
.ok();
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_for_img_buffer!(GrayImage, PixelType::U8);
|
||||
impl_for_img_buffer!(GrayAlphaImage, PixelType::U8x2);
|
||||
impl_for_img_buffer!(RgbImage, PixelType::U8x3);
|
||||
impl_for_img_buffer!(RgbaImage, PixelType::U8x4);
|
||||
|
||||
type Gray16Image = ImageBuffer<Luma<u16>, Vec<u16>>;
|
||||
impl_for_img_buffer!(Gray16Image, PixelType::U16);
|
||||
|
||||
type GrayAlpha16Image = ImageBuffer<LumaA<u16>, Vec<u16>>;
|
||||
impl_for_img_buffer!(GrayAlpha16Image, PixelType::U16x2);
|
||||
|
||||
type Rgb16Image = ImageBuffer<Rgb<u16>, Vec<u16>>;
|
||||
impl_for_img_buffer!(Rgb16Image, PixelType::U16x3);
|
||||
|
||||
type Rgba16Image = ImageBuffer<Rgba<u16>, Vec<u16>>;
|
||||
impl_for_img_buffer!(Rgba16Image, PixelType::U16x4);
|
||||
|
||||
impl_for_img_buffer!(Rgb32FImage, PixelType::F32x3);
|
||||
impl_for_img_buffer!(Rgba32FImage, PixelType::F32x4);
|
||||
|
||||
+37
-1
@@ -3,9 +3,11 @@ use fast_image_resize::images::{
|
||||
CroppedImage, CroppedImageMut, Image, ImageRef, TypedCroppedImage, TypedCroppedImageMut,
|
||||
TypedImage, TypedImageRef,
|
||||
};
|
||||
use fast_image_resize::pixels::{U8x4, U8};
|
||||
use fast_image_resize::pixels::{U8x3, U8x4, U8};
|
||||
use fast_image_resize::{ImageView, IntoImageView, PixelType, ResizeOptions};
|
||||
|
||||
mod testing;
|
||||
|
||||
#[test]
|
||||
fn create_image_ref_from_small_buffer() {
|
||||
let width = 64;
|
||||
@@ -271,3 +273,37 @@ fn use_bytemuck_to_create_typed_image_from_slice() {
|
||||
let res = TypedImageRef::new(width, height, pixels);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
mod support_of_image_crate {
|
||||
use super::*;
|
||||
use image::{DynamicImage, RgbImage};
|
||||
use testing::PixelTestingExt;
|
||||
|
||||
#[test]
|
||||
fn use_dynamic_image() {
|
||||
let width = 64;
|
||||
let height = 32;
|
||||
|
||||
let image_buffer = U8x3::load_small_image();
|
||||
let src_dynamic_image: DynamicImage = image_buffer.into();
|
||||
let mut dst_dynamic_image = DynamicImage::new_rgb8(width, height);
|
||||
|
||||
let mut resizer = fr::Resizer::new();
|
||||
let res = resizer.resize(&src_dynamic_image, &mut dst_dynamic_image, None);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn use_image_buffer() {
|
||||
let width = 64;
|
||||
let height = 32;
|
||||
|
||||
let src_image_buffer = U8x3::load_small_image();
|
||||
let mut dst_image_buffer = RgbImage::new(width, height);
|
||||
|
||||
let mut resizer = fr::Resizer::new();
|
||||
let res = resizer.resize(&src_image_buffer, &mut dst_image_buffer, None);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user