Rust图像处理库stb_image的使用,支持高效加载和解析PNG、JPG、BMP等主流图片格式
Rust图像处理库stb_image的使用,支持高效加载和解析PNG、JPG、BMP等主流图片格式
rust-stb-image是Rust语言对stb_image库的绑定实现。stb_image是一个轻量级的C语言图像加载库,支持PNG、JPG、BMP等多种主流图片格式。
安装
在项目中添加stb_image依赖:
stb_image = "0.3.0"
或者运行命令:
cargo add stb_image
使用示例
下面是一个完整的示例代码,展示如何使用stb_image加载和解析图片:
use stb_image::image::{LoadResult, Image};
fn main() {
// 加载图片文件
let image_result = Image::load("example.png");
match image_result {
LoadResult::ImageU8(image) => {
// 成功加载8位图像
println!("成功加载图片: {}x{} ({} channels)",
image.width, image.height, image.depth);
// 访问像素数据
for y in 0..image.height {
for x in 0..image.width {
let index = (y * image.width + x) * image.depth as usize;
let r = image.data[index];
let g = image.data[index + 1];
let b = image.data[index + 2];
// 处理像素数据...
}
}
}
LoadResult::ImageF32(image) => {
// 成功加载32位浮点图像
println!("成功加载浮点图像: {}x{} ({} channels)",
image.width, image.height, image.depth);
}
LoadResult::Error(error) => {
// 加载失败
eprintln!("加载图片失败: {}", error);
}
}
}
完整示例demo
下面是一个更完整的示例,展示如何加载图片并将其转换为灰度图:
use stb_image::image::{LoadResult, Image};
fn main() {
// 加载图片文件
let image_result = Image::load("input.jpg");
match image_result {
LoadResult::ImageU8(mut image) => {
println!("成功加载图片: {}x{} ({}通道)",
image.width, image.height, image.depth);
// 转换为灰度图
if image.depth >= 3 {
for i in (0..image.data.len()).step_by(image.depth as usize) {
let r = image.data[i] as f32;
let g = image.data[i + 1] as f32;
let b = image.data[i + 2] as f32;
// 计算灰度值 (使用标准灰度转换公式)
let gray = (0.299 * r + 0.587 * g + 0.114 * b) as u8;
// 将RGB通道都设为灰度值
image.data[i] = gray;
image.data[i + 1] = gray;
image.data[i + 2] = gray;
// 如果有alpha通道,保持不变
if image.depth == 4 {
// alpha通道保持不变
}
}
// 保存处理后的图片
if let Err(e) = image.save("output.jpg") {
eprintln!("保存图片失败: {}", e);
} else {
println!("灰度图已保存为output.jpg");
}
}
}
LoadResult::ImageF32(_) => {
println!("暂不支持浮点图像处理");
}
LoadResult::Error(error) => {
eprintln!("加载图片失败: {}", error);
}
}
}
功能特点
- 支持多种图片格式:PNG、JPG、BMP等
- 高效的内存使用
- 简单的API接口
- 支持8位和32位浮点图像加载
注意事项
- 当前版本使用修改版的stb_image v2.28
- 图像数据处理时需要注意通道顺序(RGBA)
- 处理图片时要注意边界检查和通道数验证
这个库特别适合需要轻量级图像加载功能的Rust项目,是游戏开发、计算机视觉等应用的理想选择。
1 回复
Rust图像处理库stb_image的使用指南
stb_image
是一个轻量级的图像加载库,Rust版本提供了对主流图片格式(PNG、JPG、BMP等)的高效加载和解析支持。
特性
- 支持多种图片格式:JPEG、PNG、BMP、PSD、TGA、GIF等
- 无外部依赖
- 内存占用小
- 简单易用的API
使用方法
添加依赖
在Cargo.toml
中添加:
[dependencies]
stb_image = "0.2"
基本用法示例
use stb_image::image;
fn main() {
// 加载图片
let image = image::load("example.jpg");
match image {
image::LoadResult::ImageU8(image) => {
println!("Loaded image: {}x{} ({} channels)",
image.width,
image.height,
image.depth);
// 访问像素数据
let pixel_data = image.data;
// 处理像素数据...
}
image::LoadResult::ImageF32(image) => {
println!("Loaded HDR image");
// 处理HDR图像...
}
image::LoadResult::Error(e) => {
eprintln!("Failed to load image: {}", e);
}
}
}
高级选项
use stb_image::image::{load_with_depth, DesiredChannels};
// 强制加载为RGB格式(3通道)
let image = load_with_depth("example.png", DesiredChannels::RGB, 3);
// 强制加载为RGBA格式(4通道)
let image = load_with_depth("example.png", DesiredChannels::RGBA, 4);
// 加载时不进行自动翻转
let image = image::load_with_flip("example.jpg", false);
保存图像
use stb_image::image::save;
// 保存为PNG格式
let pixels = vec![255, 0, 0, 255]; // 红色像素(RGBA)
save("output.png", 1, 1, 4, &pixels).unwrap();
完整示例demo
下面是一个完整的使用stb_image加载、处理和保存图像的示例:
use stb_image::image::{load, load_with_depth, DesiredChannels, save};
fn main() {
// 1. 基本加载示例
println!("=== 基本加载示例 ===");
let image = load("example.jpg");
match image {
image::LoadResult::ImageU8(img) => {
println!("成功加载图像: {}x{} ({}通道)",
img.width,
img.height,
img.depth);
// 2. 处理图像数据 - 这里简单地将图像转为灰度
println!("\n=== 图像处理示例 ===");
let mut gray_data = Vec::with_capacity(img.width * img.height);
for i in 0..img.data.len() / img.depth {
let r = img.data[i * img.depth] as f32;
let g = img.data[i * img.depth + 1] as f32;
let b = img.data[i * img.depth + 2] as f32;
// 计算灰度值
let gray = (0.299 * r + 0.587 * g + 0.114 * b) as u8;
gray_data.push(gray);
}
// 3. 保存处理后的图像
println!("\n=== 保存图像示例 ===");
save("gray_image.png", img.width, img.height, 1, &gray_data)
.expect("保存图像失败");
println!("灰度图像已保存为 gray_image.png");
}
image::LoadResult::ImageF32(_) => {
println!("加载了HDR图像,本示例不支持");
}
image::LoadResult::Error(e) => {
eprintln!("加载图像失败: {}", e);
}
}
// 4. 高级选项示例 - 强制加载为3通道RGB
println!("\n=== 高级选项示例 ===");
let rgb_image = load_with_depth("example.png", DesiredChannels::RGB, 3);
if let image::LoadResult::ImageU8(img) = rgb_image {
println!("强制加载为RGB图像成功: {}x{} ({}通道)",
img.width, img.height, img.depth);
}
}
注意事项
- 默认情况下,图像会被垂直翻转以适应OpenGL的纹理坐标系统
- 对于HDR图像,会返回
ImageF32
类型 - 图像数据以行优先顺序存储
性能提示
- 对于需要频繁加载的图像,考虑缓存加载结果
- 只加载需要的通道数可以减少内存使用
- 对于已知格式的图像,可以使用特定格式的加载函数提高性能
这个库非常适合需要轻量级图像加载功能的Rust项目,特别是在嵌入式或资源受限的环境中。