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");
}
性能建议
- 对于小图像,可以直接编码
- 对于大图像,先缩放到较小尺寸(如32x32)再编码
- x_comp和y_comp通常3-5之间,数值越大字符串越长但细节越多
应用场景
- 图片懒加载的占位符
- 低带宽环境下的图像预览
- 需要模糊敏感内容的场景
- 图像列表的快速渲染
Blurhash是优化用户体验的强大工具,特别适合需要快速显示大量图像预览的Web和移动应用。