写博客时经常会用到 tinypng 这个网站进行图片压缩,所以今天就想用 Rust 试一下关于图片处理的东西。首先对比了一个 Rust 和 Python 的缩放速度,Rust 使用了 image-rs,Python 使用了 Image 中的 PIL,速度结果如下图。

原图是一张 2.9M,4800x2500 的图片,缩小为 500x260。电脑CPU型号是 Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz。使用 release 编译。

> 点击这里查看大图

注意下图中每个图片文件的文件名,标注了 image-rs 中使用的 FilterType

可以发现,除了 image-rs 中的 Nearest 模式比较快之外,其他模式均比 Python 的 PIL 慢,因为 PIL 是C写的。

代码如下

[dependencies]
image = "0.23.4"
stopwatch = "0.0.7"
extern crate image;
extern crate stopwatch;

use image::RgbImage;
use image::DynamicImage;
use image::imageops::FilterType;
use stopwatch::{Stopwatch};


fn resize_image(){
    let origin_image = "1.jpg";
    let src_image = image::open(origin_image).unwrap();

    let nwidth: u32 = 500;
    let nheight: u32  = 260;

    resize(&src_image, nwidth, nheight, FilterType::Nearest, "1_1_Nearest.jpg");
    resize(&src_image, nwidth, nheight, FilterType::Triangle, "1_2_Traingle.jpg");
    resize(&src_image, nwidth, nheight, FilterType::CatmullRom, "1_3_CatmullRom.jpg");
    resize(&src_image, nwidth, nheight, FilterType::Gaussian, "1_4_Gaussian.jpg");
    resize(&src_image, nwidth, nheight, FilterType::Lanczos3, "1_5_Lanczos3.jpg");
}

fn resize(src_image: &DynamicImage, nwidth: u32, nheight: u32, ftype: FilterType, file_name: &str ) {
    let sw = Stopwatch::start_new();
    let new_image = src_image.resize(nwidth, nheight, ftype);
    new_image.save(file_name);
    let elapsed_ms = sw.elapsed_ms();
    println!("{:?} - {} ms", ftype, elapsed_ms);
}
from PIL import Image
import time

src_file = "1.jpg"
des_file = "1_500.jpg"
im = Image.open(src_file)

start_time = time.time();
im = im.convert('RGB')
im = im.resize((500, 260))
im.save(des_file)

end_time = time.time();

print(end_time - start_time);