mirror of
https://github.com/Cykooz/fast_image_resize.git
synced 2026-10-08 01:11:09 +00:00
Excluded "nearest" algorithm for benchmarking of "resizer" crate.
This commit is contained in:
@@ -11,6 +11,7 @@ about resizing with respect to color space._
|
||||
[CHANGELOG](https://github.com/Cykooz/fast_image_resize/blob/main/CHANGELOG.md)
|
||||
|
||||
Supported pixel formats and available optimisations:
|
||||
|
||||
- `U8` - one `u8` component per pixel:
|
||||
- native Rust-code without forced SIMD
|
||||
- SSE4.1 (partial)
|
||||
@@ -35,6 +36,7 @@ Supported pixel formats and available optimisations:
|
||||
## Benchmarks
|
||||
|
||||
Environment:
|
||||
|
||||
- CPU: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
|
||||
- RAM: DDR4 3000 MHz
|
||||
- Ubuntu 20.04 (linux 5.13)
|
||||
@@ -44,10 +46,12 @@ Environment:
|
||||
- `rustflags = ["-C", "llvm-args=-x86-branches-within-32B-boundaries"]`
|
||||
|
||||
Other Rust libraries used to compare of resizing speed:
|
||||
|
||||
- image = "0.24.1" (<https://crates.io/crates/image>)
|
||||
- resize = "0.7.2" (<https://crates.io/crates/resize>)
|
||||
|
||||
Resize algorithms:
|
||||
|
||||
- Nearest
|
||||
- Convolution with Bilinear filter
|
||||
- Convolution with CatmullRom filter
|
||||
@@ -76,7 +80,8 @@ Pipeline:
|
||||
|
||||
`src_image => multiply by alpha => resize => divide by alpha => dst_image`
|
||||
|
||||
- Source image [nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
- Source image
|
||||
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
@@ -125,7 +130,7 @@ Pipeline:
|
||||
|
||||
## Examples
|
||||
|
||||
### Resize image
|
||||
### Resize RGBA8 image
|
||||
|
||||
```rust
|
||||
use std::io::BufWriter;
|
||||
@@ -137,8 +142,7 @@ use image::{ColorType, GenericImageView};
|
||||
|
||||
use fast_image_resize as fr;
|
||||
|
||||
#[test]
|
||||
fn resize_image_example() {
|
||||
fn main() {
|
||||
// Read source image from file
|
||||
let img = ImageReader::open("./data/nasa-4928x3279.png")
|
||||
.unwrap()
|
||||
@@ -151,8 +155,7 @@ fn resize_image_example() {
|
||||
height,
|
||||
img.to_rgba8().into_raw(),
|
||||
fr::PixelType::U8x4,
|
||||
)
|
||||
.unwrap();
|
||||
).unwrap();
|
||||
|
||||
// Create MulDiv instance
|
||||
let alpha_mul_div = fr::MulDiv::default();
|
||||
@@ -196,6 +199,66 @@ fn resize_image_example() {
|
||||
}
|
||||
```
|
||||
|
||||
### Resize with cropping
|
||||
|
||||
```rust
|
||||
use std::io::BufWriter;
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use image::codecs::png::PngEncoder;
|
||||
use image::io::Reader as ImageReader;
|
||||
use image::{ColorType, GenericImageView};
|
||||
|
||||
use fast_image_resize as fr;
|
||||
|
||||
fn resize_image_with_cropping(
|
||||
mut src_view: fr::ImageView,
|
||||
dst_width: NonZeroU32,
|
||||
dst_height: NonZeroU32
|
||||
) -> fr::Image {
|
||||
// Set cropping parameters
|
||||
src_view.set_crop_box_to_fit_dst_size(dst_width, dst_height, None);
|
||||
|
||||
// Create container for data of destination image
|
||||
let mut dst_image = fr::Image::new(
|
||||
dst_width,
|
||||
dst_height,
|
||||
src_view.pixel_type(),
|
||||
);
|
||||
// Get mutable view of destination image data
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
|
||||
// Create Resizer instance and resize source image
|
||||
// into buffer of destination image
|
||||
let mut resizer = fr::Resizer::new(
|
||||
fr::ResizeAlg::Convolution(fr::FilterType::Lanczos3)
|
||||
);
|
||||
resizer.resize(&src_view, &mut dst_view).unwrap();
|
||||
|
||||
dst_image
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let img = ImageReader::open("./data/nasa-4928x3279.png")
|
||||
.unwrap()
|
||||
.decode()
|
||||
.unwrap();
|
||||
let width = NonZeroU32::new(img.width()).unwrap();
|
||||
let height = NonZeroU32::new(img.height()).unwrap();
|
||||
let src_image = fr::Image::from_vec_u8(
|
||||
width,
|
||||
height,
|
||||
img.to_rgb8().into_raw(),
|
||||
fr::PixelType::U8x3,
|
||||
).unwrap();
|
||||
resize_image_with_cropping(
|
||||
src_image.view(),
|
||||
NonZeroU32::new(1024).unwrap(),
|
||||
NonZeroU32::new(768).unwrap(),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Change CPU extensions used by resizer
|
||||
|
||||
```rust, ignore
|
||||
|
||||
@@ -12,9 +12,11 @@ const fn p(r: u8, g: u8, b: u8, a: u8) -> u32 {
|
||||
// Multiplies by alpha
|
||||
|
||||
fn get_src_image(width: NonZeroU32, height: NonZeroU32, pixel: u32) -> Image<'static> {
|
||||
let buf_size = (width.get() * height.get()) as usize;
|
||||
let buffer = vec![pixel; buf_size];
|
||||
Image::from_vec_u32(width, height, buffer, PixelType::U8x4).unwrap()
|
||||
let pixels_count = (width.get() * height.get()) as usize;
|
||||
let buffer = (0..pixels_count)
|
||||
.flat_map(|_| pixel.to_le_bytes())
|
||||
.collect();
|
||||
Image::from_vec_u8(width, height, buffer, PixelType::U8x4).unwrap()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
|
||||
@@ -41,7 +41,11 @@ pub fn bench_downscale_rgb(bench: &mut Bench) {
|
||||
let mut dst = vec![RGB::new(0, 0, 0); (new_width.get() * new_height.get()) as usize];
|
||||
bench.task(format!("resize - {}", alg_name), |task| {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => resize::Type::Point,
|
||||
"Nearest" => {
|
||||
// resizer doesn't support "nearest" algorithm
|
||||
task.iter(|| {});
|
||||
return;
|
||||
}
|
||||
"Bilinear" => resize::Type::Triangle,
|
||||
"CatmullRom" => resize::Type::Catrom,
|
||||
"Lanczos3" => resize::Type::Lanczos3,
|
||||
|
||||
@@ -42,7 +42,11 @@ pub fn bench_downscale_rgb16(bench: &mut Bench) {
|
||||
vec![RGB::new(0u16, 0u16, 0u16); (new_width.get() * new_height.get()) as usize];
|
||||
bench.task(format!("resize - {}", alg_name), |task| {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => resize::Type::Point,
|
||||
"Nearest" => {
|
||||
// resizer doesn't support "nearest" algorithm
|
||||
task.iter(|| {});
|
||||
return;
|
||||
}
|
||||
"Bilinear" => resize::Type::Triangle,
|
||||
"CatmullRom" => resize::Type::Catrom,
|
||||
"Lanczos3" => resize::Type::Lanczos3,
|
||||
|
||||
@@ -41,7 +41,11 @@ pub fn bench_downscale_rgba(bench: &mut Bench) {
|
||||
let mut dst = vec![RGBA::new(0, 0, 0, 0); (new_width.get() * new_height.get()) as usize];
|
||||
bench.task(format!("resize - {}", alg_name), |task| {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => resize::Type::Point,
|
||||
"Nearest" => {
|
||||
// resizer doesn't support "nearest" algorithm
|
||||
task.iter(|| {});
|
||||
return;
|
||||
}
|
||||
"Bilinear" => resize::Type::Triangle,
|
||||
"CatmullRom" => resize::Type::Catrom,
|
||||
"Lanczos3" => resize::Type::Lanczos3,
|
||||
@@ -104,14 +108,21 @@ pub fn bench_downscale_rgba(bench: &mut Bench) {
|
||||
}
|
||||
|
||||
bench.task(format!("fir {} - {}", ext_name, alg_name), |task| {
|
||||
task.iter(|| {
|
||||
mul_div
|
||||
.multiply_alpha(&src_view, &mut premultiplied_src_image.view_mut())
|
||||
.unwrap();
|
||||
fast_resizer
|
||||
.resize(&premultiplied_src_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
|
||||
task.iter(|| match resize_alg {
|
||||
ResizeAlg::Nearest => {
|
||||
fast_resizer
|
||||
.resize(&premultiplied_src_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
}
|
||||
_ => {
|
||||
mul_div
|
||||
.multiply_alpha(&src_view, &mut premultiplied_src_image.view_mut())
|
||||
.unwrap();
|
||||
fast_resizer
|
||||
.resize(&premultiplied_src_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
@@ -42,7 +42,11 @@ pub fn bench_downscale_u8(bench: &mut Bench) {
|
||||
let mut dst = vec![Gray(0u8); (new_width.get() * new_height.get()) as usize];
|
||||
bench.task(format!("resize - {}", alg_name), |task| {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => resize::Type::Point,
|
||||
"Nearest" => {
|
||||
// resizer doesn't support "nearest" algorithm
|
||||
task.iter(|| {});
|
||||
return;
|
||||
}
|
||||
"Bilinear" => resize::Type::Triangle,
|
||||
"CatmullRom" => resize::Type::Catrom,
|
||||
"Lanczos3" => resize::Type::Lanczos3,
|
||||
|
||||
Reference in New Issue
Block a user