34个版本

0.2.8 2024年8月23日
0.2.7 2024年8月20日
0.2.0 2024年7月29日
0.1.24 2024年7月23日
0.1.16 2024年6月21日

#58 in 图像

Download history 518/week @ 2024-06-01 162/week @ 2024-06-08 1227/week @ 2024-06-15 129/week @ 2024-06-22 1/week @ 2024-06-29 47/week @ 2024-07-06 377/week @ 2024-07-13 504/week @ 2024-07-20 174/week @ 2024-07-27 354/week @ 2024-08-03 16/week @ 2024-08-10 631/week @ 2024-08-17

1,197 每月下载量

Apache-2.0 OR BSD-3-Clause

1MB
25K SLoC

Rust图像缩放库

使用SIMD和多线程在Rust中对不同色彩空间进行图像缩放。

支持NEON、SSE、AVX-2、RISC-V(向量扩展)。

色彩空间

此库为您提供在不同色彩空间中缩放的便利。
预构建选项包括CIE L*a*b、CIE L*u*v、CIE L*c*h、线性、Sigmoidal、Oklab、Jzazbz。
这些转换也非常高效。建议在线性色彩空间或XYZ中进行降级。
升级可能通过LAB/LUB和模拟化组件进行,在sRGB中也同样高效。

具有良好的f16(二进制浮点16)支持。

使用image crate的示例集成

let img = ImageReader::open("./assets/asset.png")
    .unwrap()
    .decode()
    .unwrap();
let dimensions = img.dimensions();
let mut bytes = Vec::from(img.as_bytes());

let mut scaler = LinearScaler::new(ResamplingFunction::Lanczos3);
scaler.set_threading_policy(ThreadingPolicy::Adaptive);
// ImageStore::<u8, 4> - (u8, 4) represents RGBA, (u8, 3) - RGB etc
let store =
    ImageStore::<u8, 4>::from_slice(&mut bytes, dimensions.0 as usize, dimensions.1 as usize).unwrap();
let resized = scaler.resize_rgba(
    ImageSize::new(dimensions.0 as usize / 2, dimensions.1 as usize / 2),
    store,
    true
);
let resized_image = resized.as_bytes();

使用SIMD的最快路径

尽管所有实现都很快,但并非所有路径都使用SIMD实现,因此某些路径较慢

~ - 部分实现

NEON SSE AVX RISC-V WASM
RGBA (8位) x x ~ x x
RGB (8位) x x ~ ~ x
平面 (8位) x x ~ ~ ~
RGBA (8+位) x x ~ - -
RGB (8+位) x x ~ - -
平面 (8+位) ~ ~ ~ - -
RGBA (f32) x x x x -
RGB (f32) x x ~ ~ -
平面 (f32) x x ~ ~ -
RGBA (f16) x x x x -
RGB (f16) x ~ ~ ~ -
平面 (f16) ~ ~ ~ ~ -

特性

对于RISC-V riscv特性应隐式启用,需要夜间编译器通道。

要启用对f16的支持,应激活half特性。

目标特性

neon可选目标特性可用,在支持的平台上进行编译时启用它以获取完整特性

avx2fmasse4.1f16c将在可用时自动检测,并调用最佳路径

fullfp16 NEON目标检测在运行时执行,当可用时,在ARM上提供最佳路径以处理f16图像。

如果启用特性 riscv 并且可用,则在运行时将检测到 RISC-V V (向量扩展)。需要使用 Nightly rust 频道。

在构建标志中强制激活 WASM simd128 目标特性。

关于 f16

要启用对 f16 的全面支持,应使用 half 特性,并在针对 x86 平台时启用 f16c》。对于 NEON f16 特性,使用运行时检测,如果 CPU 支持此特性,则可使用非常快速的路径。

即使激活了 half 特性,但平台不支持或未启用 f16 特性,速度将较慢。

对于 RISC-V Vzfh,以及 zvfh,需要 CPU 支持,以使用最快的路径。

性能

以下是使用 fast-image-resize 时间比较,将 RGB 4928x3279 图像缩小两倍。

Lanczos3 SSE AVX NEON
pic-scale 43.84 33.98 23.48
fir sse 45.36 36.05 36.69

使用预乘 alpha 的 RGBA 4928x3279 图像在两倍缩小时的比较示例时间。

Lanczos3 SSE AVX NEON
pic-scale 68.51 47.33 35.67
fir sse 73.28 54.66 54.66

不使用预乘 alpha 的 RGBA 4928x3279 图像在两倍缩小时的比较示例时间。

Lanczos3 SSE AVX NEON
pic-scale 52.42 38.37 28.75
fir sse 51.89 39.82 44.54

使用预乘 alpha 的 RGBA 4928x3279 10 位图像在两倍缩小时的比较示例时间。

Lanczos3 SSE NEON
pic-scale 156.90 62.44
fir sse 150.65 91.08

不使用预乘 alpha 的 RGBA 4928x3279 10 位图像在两倍缩小。

Lanczos3 SSE NEON
pic-scale 156.90 45.09
fir sse 150.65 73.82

使用 NEON 将 RGB 4000x6000 10 位图像缩小两倍的比较示例时间。

Lanczos3 SSE NEON
pic-scale 138.75 56.89
fir sse 125.85 100.36

在 sRGB 中的示例

通常,您不应在 sRGB 颜色空间中缩小图像,但如果速度比更合适的缩放更重要,则可以省略线性化。

let mut scaler = Scaler::new(ResamplingFunction::Hermite);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
    ImageStore::<u8, 4>::from_slice(&mut bytes, width, height).unwrap();
let resized = scaler.resize_rgba(
    ImageSize::new(new_width, new_height),
    store,
    true
);

在线性中的示例

目前仅支持 sRGB 转换函数。这也是一个很好的优化路径,因此速度相当快。

let mut scaler = LinearScaler::new(ResamplingFunction::Lanczos3);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
    ImageStore::<u8, 4>::from_slice(&mut bytes, width, height).unwrap();
let resized = scaler.resize_rgba(
    ImageSize::new(new_width, new_height),
    store,
    true
);

CIE L*a*b 中的示例

let mut scaler = LabScaler::new(ResamplingFunction::Hermite);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
    ImageStore::<u8, 4>::from_slice(&mut bytes, width, height).unwrap();
let resized = scaler.resize_rgba(
    ImageSize::new(new_width, new_height),
    store,
    true
);

CIE L*u*v 中的示例

let mut scaler = LuvScaler::new(ResamplingFunction::Hermite);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
    ImageStore::<u8, 4>::from_slice(&mut bytes, width, height).unwrap();
let resized = scaler.resize_rgba(
    ImageSize::new(new_width, new_height),
    store,
    true
);

CIE XYZ 颜色空间中的示例

let mut scaler = XYZScale::new(ResamplingFunction::Hermite);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
    ImageStore::<u8, 4>::from_slice(&mut bytes, width, height).unwrap();
let resized = scaler.resize_rgba(
    ImageSize::new(new_width, new_height),
    store,
    true
);

sigmoidal 颜色空间中的示例

let mut scaler = SigmoidalScaler::new(ResamplingFunction::Hermite);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
    ImageStore::<u8, 4>::from_slice(&mut bytes, width, height).unwrap();
let resized = scaler.resize_rgba(
    ImageSize::new(new_width, new_height),
    store,
    true
);

LCh 颜色空间中的示例

let mut scaler = LChScaler::new(ResamplingFunction::Hermite);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
    ImageStore::<u8, 4>::from_slice(&mut bytes, width, height).unwrap();
let resized = scaler.resize_rgba(
    ImageSize::new(new_width, new_height),
    store,
    true
);

Oklab 颜色空间中的示例

let mut scaler = OklabScaler::new(ResamplingFunction::Hermite);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
    ImageStore::<u8, 4>::from_slice(&mut bytes, width, height).unwrap();
let resized = scaler.resize_rgba(
    ImageSize::new(new_width, new_height),
    store,
    true
);

重采样滤波器

支持超过 30 种重采样滤波器。

Bilinear
Nearest
Cubic
MitchellNetravalli
CatmullRom
Hermite
BSpline
Hann
Bicubic
Hamming
Hanning
Blackman

以及其他

依赖项

~3MB
~68K SLoC