Rust图像处理库blurhash的使用,快速生成轻量级图像模糊哈希字符串实现高效占位

Rust图像处理库blurhash的使用,快速生成轻量级图像模糊哈希字符串实现高效占位

blurhash-rs是Blurhash算法的纯Rust实现。Blurhash是由Dag Ågren为Wolt开发的算法,可以将图像编码为短字符串(约20-30字节)。当解码字符串回图像时,你会得到一个代表原始图像的彩色渐变。这在需要图像加载前的占位符场景中非常有用。

使用方法

Cargo.toml中添加依赖:

[dependencies]
blurhash = "0.2.3"

默认情况下启用了fast-linear-to-srgb功能,这可以提高约60%的解码性能,但有8KB的内存开销。如果这有问题,可以禁用默认功能:

[dependencies]
blurhash = { version = "0.2.3", default-features = false }

编码示例

use blurhash::encode;
use image::GenericImageView;

fn main() {
  // 添加image到你的Cargo.toml
  let img = image::open("octocat.png").unwrap();
  let (width, height) = img.dimensions();
  let blurhash = encode(4, 3, width, height, &img.to_rgba().into_vec());
}

解码示例

use blurhash::decode;

let pixels = decode("LBAdAqof00WCqZj[PDay0.WB}pof", 50, 50, 1.0);

完整示例代码

下面是一个完整的示例,展示如何使用blurhash库进行图像编码和解码:

use blurhash::{encode, decode};
use image::{GenericImageView, ImageBuffer, Rgba};
use std::path::Path;

fn main() {
    // 编码示例
    let img = image::open("input.png").expect("无法打开图像文件");
    let (width, height) = img.dimensions();
    
    // 将图像转换为RGBA格式的字节向量
    let rgba = img.to_rgba();
    let bytes = rgba.into_raw();
    
    // 生成blurhash字符串 (x_components, y_components, width, height, pixels)
    let blurhash_str = encode(4, 3, width, height, &bytes);
    println!("生成的Blurhash: {}", blurhash_str);
    
    // 解码示例
    let decoded_pixels = decode(&blurhash_str, 100, 100, 1.0)
        .expect("解码Blurhash失败");
    
    // 创建ImageBuffer从解码的像素
    let img_buf = ImageBuffer::from_fn(100, 100, |x, y| {
        let base = (y * 100 + x) as usize * 4;
        Rgba([
            decoded_pixels[base],
            decoded_pixels[base + 1],
            decoded_pixels[base + 2],
            decoded_pixels[base + 3],
        ])
    });
    
    // 保存解码后的图像
    img_buf.save("output.png").expect("无法保存解码图像");
}

许可证

该项目采用以下任一许可证:

  • Apache License, Version 2.0
  • MIT license

1 回复

Rust图像处理库blurhash的使用:快速生成轻量级图像模糊哈希字符串

介绍

Blurhash是一种紧凑的表示图像占位符的算法,它能将图像转换为一个短字符串(约20-30个字符),这个字符串可以解码回一个小型的模糊图像。Rust的blurhash库实现了这一算法,非常适合需要快速显示图像预览的场景。

主要特点

  • 轻量级:生成的哈希字符串非常短
  • 快速:编码解码速度极快
  • 跨平台:可以与其他语言的Blurhash实现互操作
  • 无依赖:纯Rust实现

使用方法

添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
blurhash = "0.2"

基本用法示例

1. 编码图像为Blurhash字符串

use blurhash::encode;
use image::open;

fn main() {
    // 加载图像
    let img = open("example.jpg").unwrap().to_rgba8();
    
    // 获取图像尺寸
    let width = img.width();
    let height = img.height();
    
    // 编码为Blurhash (x_comp和y_comp控制细节程度,通常4x3或3x4)
    let blurhash_str = encode(4, 3, width, height, &img).unwrap();
    
    println!("生成的Blurhash: {}", blurhash_str);
    // 示例输出: "LEHV6nWB2yk8pyoJadR*.7kCMdnj"
}

2. 解码Blurhash字符串为图像

use blurhash::decode;
use image::{ImageBuffer, Rgba};

fn main() {
    let blurhash_str = "LEHV6nWB2yk8pyoJadR*.7kCMdnj";
    
    // 解码为图像 (这里设置为100x100像素)
    let pixels = decode(blurhash_str, 100, 100, 1.0).unwrap();
    
    // 创建图像缓冲区
    let mut img = ImageBuffer::new(100, 100);
    
    // 填充像素数据
    for (x, y, pixel) in img.enumerate_pixels_mut() {
        let index = (y * 100 + x) as usize * 4;
        *pixel = Rgba([
            pixels[index],
            pixels[index + 1],
            pixels[index + 2],
            pixels[index + 3],
        ]);
    }
    
    // 保存图像
    img.save("blurhash_output.png").unwrap();
}

高级用法

自定义编码参数

use blurhash::encode;

fn custom_encode() {
    let img = image::open("photo.png").unwrap().to_rgba8();
    let (width, height) = (img.width(), img.height());
    
    // 使用不同的x/y组件数 (影响细节和字符串长度)
    let blurhash = encode(5, 4, width, height, &img).unwrap();
    println!("更详细的Blurhash: {}", blurhash);
}

与Web应用集成

use blurhash::decode_into_image_buffer;

async fn load_image_with_placeholder(blurhash_str: &str, url: &str) {
    // 1. 先显示Blurhash占位符
    let placeholder = decode_into_image_buffer(blurhash_str, 300, 200, 1.0)
        .unwrap();
    
    // 显示placeholder...
    
    // 2. 异步加载实际图像
    let real_image = reqwest::get(url).await.unwrap()
        .bytes().await.unwrap();
    
    // 替换为真实图像...
}

完整示例demo

下面是一个完整的示例,展示如何从图像生成Blurhash,然后再解码回模糊图像:

use blurhash::{encode, decode};
use image::{open, ImageBuffer, Rgba};

fn main() {
    // 1. 编码示例
    let img = open("input.jpg").expect("无法加载图像").to_rgba8();
    let (width, height) = (img.width(), img.height());
    
    // 编码为Blurhash字符串
    let blurhash_str = encode(4, 3, width, height, &img).expect("编码失败");
    println!("生成的Blurhash: {}", blurhash_str);
    
    // 2. 解码示例
    // 设置输出图像尺寸
    let output_width = 200;
    let output_height = 150;
    
    // 解码Blurhash字符串
    let pixels = decode(&blurhash_str, output_width, output_height, 1.0)
        .expect("解码失败");
    
    // 创建图像缓冲区
    let mut img_buffer = ImageBuffer::new(output_width, output_height);
    
    // 填充像素数据
    for (x, y, pixel) in img_buffer.enumerate_pixels_mut() {
        let index = (y * output_width + x) as usize * 4;
        *pixel = Rgba([
            pixels[index],
            pixels[index + 1],
            pixels[index + 2],
            pixels[index + 3],
        ]);
    }
    
    // 保存解码后的模糊图像
    img_buffer.save("blurred_output.png").expect("保存失败");
    println!("已保存模糊图像到 blurred_output.png");
}

性能建议

  1. 对于小图像,可以直接编码
  2. 对于大图像,先缩放到较小尺寸(如32x32)再编码
  3. x_comp和y_comp通常3-5之间,数值越大字符串越长但细节越多

应用场景

  • 图片懒加载的占位符
  • 低带宽环境下的图像预览
  • 需要模糊敏感内容的场景
  • 图像列表的快速渲染

Blurhash是优化用户体验的强大工具,特别适合需要快速显示大量图像预览的Web和移动应用。

回到顶部