Skip to content

Commit

Permalink
refactor: use SIMD for image resizing
Browse files Browse the repository at this point in the history
  • Loading branch information
goweiwen committed Sep 12, 2023
1 parent 7b699a9 commit 919320a
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 8 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ embedded-graphics-simulator = { version = "0.5.0", optional = true }
sdl2 = { version = "0.35.2", optional = true }
sysfs_gpio = { version = "0.6.1", optional = true }
wait-timeout = "0.2.0"
fast_image_resize = "2.7.3"

[target.'cfg(target_arch = "arm")'.dependencies]
evdev = { version = "0.12.1", features = ["tokio"], optional = true }
Expand Down
62 changes: 54 additions & 8 deletions common/src/view/image.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::VecDeque;
use std::num::NonZeroU32;
use std::path::{Path, PathBuf};

use anyhow::Result;
Expand Down Expand Up @@ -141,20 +142,65 @@ impl View for Image {
}

fn image(path: &Path, rect: Rect, mode: ImageMode, border_radius: u32) -> Option<RgbaImage> {
let mut image = ::image::open(path)
let image = ::image::open(path)
.map_err(|e| error!("Failed to load image at {}: {}", path.display(), e))
.ok()?;
match mode {
ImageMode::Raw => {}
let mut image = match mode {
ImageMode::Raw => image.to_rgba8(),
ImageMode::Cover => {
image = image.resize_to_fill(rect.w, rect.h, image::imageops::FilterType::Nearest);
if image.width() == rect.w && image.height() == rect.h {
image.to_rgba8()
} else {
let src_image = fast_image_resize::Image::from_vec_u8(
NonZeroU32::new(image.width())?,
NonZeroU32::new(image.height())?,
image.to_rgba8().into_raw(),
fast_image_resize::PixelType::U8x3,
)
.map_err(|e| error!("Failed to load image at {}: {}", path.display(), e))
.ok()?;
let mut dst_image = fast_image_resize::Image::new(
NonZeroU32::new(rect.w)?,
NonZeroU32::new(rect.h)?,
src_image.pixel_type(),
);
let mut resizer =
fast_image_resize::Resizer::new(fast_image_resize::ResizeAlg::Nearest);
resizer
.resize(&src_image.view(), &mut dst_image.view_mut())
.ok()?;
RgbaImage::from_raw(rect.w, rect.h, dst_image.into_vec())?
}
}
ImageMode::Contain => {
let new_height = rect.h.min(rect.w * image.height() / image.width());
image = image.resize_to_fill(rect.w, new_height, image::imageops::FilterType::Nearest);
println!("contain!: {:?}", rect);
if image.width() == rect.w && image.height() == rect.h {
image.to_rgba8()
} else {
let new_height = rect.h.min(rect.w * image.height() / image.width());
let src_image = fast_image_resize::Image::from_vec_u8(
NonZeroU32::new(image.width())?,
NonZeroU32::new(image.height())?,
image.to_rgba8().into_raw(),
fast_image_resize::PixelType::U8x4,
)
.map_err(|e| error!("Failed to load image at {}: {}", path.display(), e))
.ok()?;
let mut dst_image = fast_image_resize::Image::new(
NonZeroU32::new(rect.w)?,
NonZeroU32::new(new_height)?,
src_image.pixel_type(),
);
let mut resizer =
fast_image_resize::Resizer::new(fast_image_resize::ResizeAlg::Nearest);
resizer
.resize(&src_image.view(), &mut dst_image.view_mut())
.ok()?;
RgbaImage::from_raw(rect.w, new_height, dst_image.into_vec())?
}
}
}
let mut image = image.to_rgba8();
};
println!("image: {:?}", image.dimensions());
if border_radius != 0 {
round(&mut image, border_radius);
}
Expand Down

0 comments on commit 919320a

Please sign in to comment.