< 返回版块

imoegirl 发表于 2020-04-26 18:18

Rust 使用 image-rs,Python使用 Image 中的 PIL,将一个 4800x2500 分辨率的图片,缩小成 500x260 分辨率的图片。下面的图是结果,前五张是 Rust 使用不同的FilterType的结果,最后一张是 Python 的结果。(图片名标识了FilterType不同的模式)

>>> 点这里查看大图

从结果可以看出,Rust使用 Nearst模式是最快的,也是效果最差的,后面的模式看起来与Python的结果区别不是很大,但是耗时却很长。想问一下这是为什么。

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);

评论区

写评论
jmjoy 2020-04-30 13:10

image-rs是挺慢的,所以我搞了graphicsmagick的绑定库了,比较适合这图形学不太了解的人使用(包括我):https://github.com/jmjoy/graphicsmagick-rs,大佬级别可以是用opencv

solarsail 2020-04-29 22:54

可以在 lib.rs 里搜一下,比如用关键字 image

对以下内容的回复:

作者 imoegirl 2020-04-27 12:12

谢谢指点,还想问一下,如果还想对图片进行其他的处理,例如压缩之类的,有什么好用的库吗? 对以下内容的回复:

作者 imoegirl 2020-04-27 12:09

是 release 模式,如果用Debug模式,那要慢个好几倍了 对以下内容的回复:

solarsail 2020-04-26 23:10

另外,PIL 底层是 C 实现的,不比 Rust 慢也正常。

solarsail 2020-04-26 22:49

image-rs 确实慢些,如果只做缩放的话,可以试试 resize

$ cargo run --release
    Finished release [optimized] target(s) in 0.08s
     Running `target/release/resizetest`
Point - 38 ms
Triangle (bilinear) - 303 ms
Catmull-Rom (bicubic) - 385 ms
Mitchell - 369 ms
Lanczos3 - 413 ms
use image::{GenericImageView, ImageBuffer, Rgb};
use resize::{Pixel::RGB24, Type};
use stopwatch::Stopwatch;

fn resize_image() {
    let src_image = image::open("1.jpg").unwrap();
    let sw = src_image.width() as usize;
    let sh = src_image.height() as usize;
    let buf = src_image.into_rgb().into_raw();

    let nwidth = 500;
    let nheight = 260;

    let dst = &mut [0u8; 500 * 260 * 3];

    resize(&buf, dst, sw, sh, nwidth, nheight, Type::Point, "2_1_Point.jpg");
    resize(&buf, dst, sw, sh, nwidth, nheight, Type::Triangle, "2_2_Triangle.jpg");
    resize(&buf, dst, sw, sh, nwidth, nheight, Type::Catrom, "2_3_Catrom.jpg");
    resize(&buf, dst, sw, sh, nwidth, nheight, Type::Mitchell, "2_4_Mitchell.jpg");
    resize(&buf, dst, sw, sh, nwidth, nheight, Type::Lanczos3, "2_5_Lanczos3.jpg");
}

fn resize(src_buf: &[u8], dst_buf: &mut [u8], sw: usize, sh: usize, dw: usize, dh: usize, ftype: resize::Type, filename: &str) {
    let ft = match ftype {
        Type::Point => "Point",
        Type::Triangle => "Triangle (bilinear)",
        Type::Catrom => "Catmull-Rom (bicubic)",
        Type::Mitchell => "Mitchell",
        Type::Lanczos3 => "Lanczos3",
        Type::Custom(_) => "Custom",
    };
    let w = Stopwatch::start_new();
    resize::resize(sw, sh, dw, dh, RGB24, ftype, src_buf, dst_buf);

    let img: ImageBuffer<Rgb<u8>, _> =
        ImageBuffer::from_raw(dw as u32, dh as u32, dst_buf).unwrap();
    img.save(filename).unwrap();
    let elapsed_ms = w.elapsed_ms();
    println!("{} - {} ms", ft, elapsed_ms);
}
PokxCuq 2020-04-26 21:15

库自己也是有锅的,在这个站的公众号此库的介绍里,DC佬简单谈了下慢的原因,也说了作者不接受改进的pr(当然我不知道为什么,可能pr的实现太烂了?)

phper-chen 2020-04-26 20:24

是release模式吗 还有rust优化参数有选吗

1 共 8 条评论, 1 页