#image-resizing #resize #pixel-format #image

fast_image_resize

使用 SIMD 指令进行快速图像缩放的库

39 个版本 (19 个稳定版)

4.2.1 2024 年 7 月 24 日
4.0.0 2024 年 5 月 13 日
3.0.4 2024 年 2 月 15 日
2.7.3 2023 年 5 月 7 日
0.1.0 2021 年 7 月 31 日

#3 in 图像

Download history 9344/week @ 2024-05-04 13407/week @ 2024-05-11 22123/week @ 2024-05-18 13977/week @ 2024-05-25 13454/week @ 2024-06-01 19553/week @ 2024-06-08 14526/week @ 2024-06-15 13892/week @ 2024-06-22 12423/week @ 2024-06-29 12087/week @ 2024-07-06 9763/week @ 2024-07-13 12641/week @ 2024-07-20 40082/week @ 2024-07-27 35856/week @ 2024-08-03 66018/week @ 2024-08-10 77461/week @ 2024-08-17

每月 221,349 次下载
31 个 crate(23 个直接) 中使用

MIT/Apache

1MB
19K SLoC

fast_image_resize

github crates.io docs.rs

Rust 单线程快速图像缩放库,使用 SIMD 指令。

变更日志

支持的像素格式和可用的优化

格式 描述 SSE4.1 AVX2 Neon Wasm32 SIMD128
U8 每个像素一个 u8 组件(例如 L) + + + +
U8x2 每个像素两个 u8 组件(例如 LA) + + + +
U8x3 每个像素三个 u8 组件(例如 RGB) + + + +
U8x4 每个像素四个 u8 组件(例如 RGBA、RGBx、CMYK) + + + +
U16 每个像素一个 u16 组件(例如 L16) + + + +
U16x2 每个像素两个 u16 组件(例如 LA16) + + + +
U16x3 每个像素三个 u16 组件(例如 RGB16) + + + +
U16x4 每个像素四个 u16 组件(例如 RGBA16、RGBx16、CMYK16) + + + +
I32 每个像素一个 i32 组件(例如 L32) - - - -
F32 每个像素一个 f32 组件(例如 L32F) + + - -
F32x2 每个像素两个 f32 组件(例如 LA32F) + + - -
F32x3 每个像素三个 f32 组件(例如 RGB32F) + + - -
F32x4 每个像素四个 f32 组件(例如 RGBA32F) + + - -

色彩空间

此存储库中的Resizer在调整大小过程中不会将图像转换为线性色彩空间。如果您需要正确调整具有非线性色彩空间(例如sRGB)的图像大小,则必须在调整大小之前将其转换为线性色彩空间,并在转换回结果图像的色彩空间之后。了解更多关于色彩空间调整大小的信息请点击这里

此存储库提供了PixelComponentMapper结构,允许您为基于u8和u16组件的像素创建色彩空间转换器。

此外,存储库包含函数create_gamma_22_mapper()create_srgb_mapper(),用于创建将图像从sRGB或伽玛2.2转换为线性色彩空间并返回的PixelComponentMapper实例。

x86_64的一些基准测试

所有基准测试: x86_64ARM64WASM32

用于比较调整大小速度的其他库

调整RGB8图像(U8x3)4928x3279 => 852x567

管道

src_image=>resize=>dst_image

  • 源图像 nasa-4928x3279.png
  • 表中的数字表示图像调整大小的时间,单位为毫秒。
最近邻 双线性 双三次 Lanczos3
image 32.17 - 94.60 153.14 211.14
resize 9.18 26.68 49.76 96.06 141.84
libvips 7.75 59.58 19.81 30.46 39.96
fir rust 0.29 11.99 16.56 25.93 37.85
fir sse4.1 0.29 4.13 5.67 9.77 15.52
fir avx2 0.29 3.13 3.98 6.88 13.18

调整RGBA8图像(U8x4)4928x3279 => 852x567

管道

src_image=>乘以alpha=>resize=>除以alpha=>dst_image

  • 源图像 nasa-4928x3279-rgba.png
  • 表中的数字表示图像调整大小的时间,单位为毫秒。
  • image存储库不支持乘以和除以alpha通道。
最近邻 双线性 双三次 Lanczos3
resize 11.98 43.60 86.90 147.95 211.64
libvips 10.06 122.00 188.57 336.42 499.80
fir rust 0.19 22.02 26.95 38.41 51.70
fir sse4.1 0.19 10.32 12.59 18.10 24.95
fir avx2 0.19 7.75 8.88 13.78 22.12

调整L8图像(U8)4928x3279 => 852x567

管道

src_image=>resize=>dst_image

  • 源图像 nasa-4928x3279.png已转换为单字节的灰度图像。
  • 表中的数字表示图像调整大小的时间,单位为毫秒。
最近邻 双线性 双三次 Lanczos3
image 28.76 - 60.68 89.41 117.41
resize 6.40 11.24 20.84 42.92 68.93
libvips 4.66 25.06 9.67 13.27 17.99
fir rust 0.15 4.74 6.02 8.41 12.62
fir sse4.1 0.15 1.67 2.14 3.31 5.61
fir avx2 0.15 1.74 1.91 2.31 4.16

示例

调整RGBA8图像

注意:您必须启用"image"功能以支持image::DynamicImage。否则,您必须将这些图像转换为存储库支持的图像类型。

use std::io::BufWriter;

use image::codecs::png::PngEncoder;
use image::io::Reader as ImageReader;
use image::{ExtendedColorType, ImageEncoder};

use fast_image_resize::{IntoImageView, Resizer};
use fast_image_resize::images::Image;

fn main() {
    // Read source image from file
    let src_image = ImageReader::open("./data/nasa-4928x3279.png")
        .unwrap()
        .decode()
        .unwrap();

    // Create container for data of destination image
    let dst_width = 1024;
    let dst_height = 768;
    let mut dst_image = Image::new(
        dst_width,
        dst_height,
        src_image.pixel_type().unwrap(),
    );

    // Create Resizer instance and resize source image
    // into buffer of destination image
    let mut resizer = Resizer::new();
    resizer.resize(&src_image, &mut dst_image, None).unwrap();

    // Write destination image as PNG-file
    let mut result_buf = BufWriter::new(Vec::new());
    PngEncoder::new(&mut result_buf)
        .write_image(
            dst_image.buffer(),
            dst_width,
            dst_height,
            src_image.color().into(),
        )
        .unwrap();
}

带有裁剪的调整

use image::codecs::png::PngEncoder;
use image::io::Reader as ImageReader;
use image::{ColorType, GenericImageView};

use fast_image_resize::{IntoImageView, Resizer, ResizeOptions};
use fast_image_resize::images::Image;

fn main() {
    let img = ImageReader::open("./data/nasa-4928x3279.png")
        .unwrap()
        .decode()
        .unwrap();

    // Create container for data of destination image
    let mut dst_image = Image::new(
        1024,
        768,
        img.pixel_type().unwrap(),
    );

    // Create Resizer instance and resize cropped source image
    // into buffer of destination image
    let mut resizer = Resizer::new();
    resizer.resize(
        &img,
        &mut dst_image,
        &ResizeOptions::new().crop(
            10.0,   // left 
            10.0,   // top
            2000.0, // width
            2000.0, // height
        ),
    ).unwrap();
}

更改调整大小程序使用的CPU扩展

use fast_image_resize as fr;

fn main() {
    let mut resizer = fr::Resizer::new();
    #[cfg(target_arch = "x86_64")]
    unsafe {
        resizer.set_cpu_extensions(fr::CpuExtensions::Sse4_1);
    }
}

依赖项

~0.6–1.4MB
~30K SLoC