轻量级单文件图像解码库 - stb_image 开源库
一. 库简介
stb_image
是一个轻量级的单文件图像解码库,由 Sean T. Barrett 开发,支持多种常见图像格式(如 JPEG、PNG、BMP、GIF、HDR 等),具有以下特点:
- 单文件实现:仅需包含
stb_image.h
头文件即可使用,无需编译库或复杂配置。 - 跨平台:支持 Windows、Linux、macOS 等系统。
- 简单接口:提供
stbi_load
、stbi_image_free
等函数,简化图像加载流程。 - 开源协议:采用公共领域(Public Domain)或 MIT 许可,可自由用于商业和非商业项目。
二. 下载地址
GitHub 仓库:
https://github.com/nothings/stb
国内镜像 gitee 仓库:
https://gitee.com/lengjianjun/stb.git
可直接克隆仓库或下载单个头文件:
git clone https://github.com/nothings/stb.git
- 关键文件:
stb_image.h
(图像加载)、stb_image_write.h
(图像保存)、stb_image_resize.h
(图像缩放)。
三. 使用步骤
3.1 配置项目
- 添加头文件:将
stb_image.h
复制到项目目录,或设置头文件路径(如通过 IDE 的附加包含目录)。 - 启用实现:在代码中仅一个源文件内定义宏
STB_IMAGE_IMPLEMENTATION
:#define STB_IMAGE_IMPLEMENTATION #include "stb_image.h"
3.2 加载图像
使用 stbi_load
函数加载图像数据:
int width, height, channels;
unsigned char *image_data = stbi_load("input.jpg", &width, &height, &channels, 0);
if (image_data == NULL) {
fprintf(stderr, "Error: %s\n", stbi_failure_reason());
return 1;
}
- 参数说明:
filename
:图像文件路径。width
/height
:返回图像的宽高。channels
:返回颜色通道数(1-灰度,3-RGB,4-RGBA)。req_comp
:指定期望通道数(0 表示保留原始格式)。
3.3 处理图像数据
访问像素数据(示例:读取第一个像素的 RGB 值):
unsigned char r = image_data[0];
unsigned char g = image_data[1];
unsigned char b = image_data[2];
3.4 释放内存
加载后需手动释放内存:
stbi_image_free(image_data);
四. 完整示例
示例 1:加载图像并输出基本信息
#include <stdio.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
int main() {
int width, height, channels;
unsigned char *data = stbi_load("test.png", &width, &height, &channels, 0);
if (!data) {
printf("Error: %s\n", stbi_failure_reason());
return 1;
}
printf("Width: %d, Height: %d, Channels: %d\n", width, height, channels);
stbi_image_free(data);
return 0;
}
编译指令:
在linux环境下编译时,需要链接数学库,在编译语句后面加一个 -lm
gcc main.c -o main -lm
如果不添加链接库,则会报错,提示 对‘pow’未定义的引用 报错如下:
/tmp/cc1aZZzs.o:在函数‘stbi__ldr_to_hdr’中:
main.c:(.text+0x2ca6):对‘pow’未定义的引用
/tmp/cc1aZZzs.o:在函数‘stbi__hdr_to_ldr’中:
main.c:(.text+0x2e6c):对‘pow’未定义的引用
collect2: error: ld returned 1 exit status
工程结构:
测试结果:
示例 2:读取图像文件并以十六进制格式显示像素数据
#include <stdio.h>
#include <stdlib.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
// 显示前 N 个字节的十六进制数据(避免输出过长)
#define SHOW_MAX_BYTES 100
int main() {
int width, height, channels;
const char *filename = "test.png"; // 图片路径
// 加载图像(自动识别格式)
unsigned char *image_data = stbi_load(filename, &width, &height, &channels, 0);
if (image_data == NULL) {
fprintf(stderr, "Error: Failed to load image '%s'\n", filename);
fprintf(stderr, "Reason: %s\n", stbi_failure_reason());
return 1;
}
// 输出基本信息
printf("Image loaded successfully!\n");
printf("Width: %d, Height: %d, Channels: %d\n", width, height, channels);
printf("Total bytes: %zu\n", width * height * channels);
// 计算实际显示的字节数
size_t total_bytes = width * height * channels;
size_t show_bytes = (total_bytes < SHOW_MAX_BYTES) ? total_bytes : SHOW_MAX_BYTES;
// 以十六进制格式显示像素数据
printf("\nFirst %zu bytes (Hex):\n", show_bytes);
for (size_t i = 0; i < show_bytes; i++) {
printf("%02X ", image_data[i]);
// 每16字节换行
if ((i + 1) % 16 == 0) {
printf("\n");
}
}
// 释放内存
stbi_image_free(image_data);
return 0;
}
示例 3:修改像素并保存图像
(需 stb_image_write.h
)
#include <stdio.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
int main() {
int line=0;
int width, height, channels;
unsigned char *data = stbi_load("input.png", &width, &height, &channels, 0);
if (!data) return 1;
printf("Image loaded successfully!\n");
printf("Width: %d, Height: %d, Channels: %d\n", width, height, channels);
// 修改第 10 行前 10 个像素为红色(RGBA)
line=10;
for (int i = 0; i < 10; i++)
{
int idx = (line * width + i) * channels;
data[idx] = 255; // R
data[idx + 1] = 0; // G
data[idx + 2] = 0; // B
if (channels == 4) data[idx + 3] = 255; // Alpha
}
// 修改第 20 行前 100 个像素为红色(RGBA)
line=20;
for (int i = 0; i < 100; i++)
{
int idx = (line * width + i) * channels;
data[idx] = 255; // R
data[idx + 1] = 0; // G
data[idx + 2] = 0; // B
if (channels == 4) data[idx + 3] = 255; // Alpha
}
stbi_write_png("output.png", width, height, channels, data, width * channels);
stbi_image_free(data);
return 0;
}
打印信息:
原图
输出:
- 注意事项:
- 确保图像文件路径正确。
- 若需保存图像,需额外包含
stb_image_write.h
并定义STB_IMAGE_WRITE_IMPLEMENTATION
。
五. 扩展功能
- 图像缩放:使用
stb_image_resize.h
调整尺寸(需定义STB_IMAGE_RESIZE_IMPLEMENTATION
)。 - 内存加载:通过
stbi_load_from_memory
从内存加载图像数据。 - 格式支持:支持保存为 PNG、JPG 等格式(
stbi_write_png
、stbi_write_jpg
)。
六. 常见问题
- 图像通道顺序:RGB(默认)或 BGR(如 BMP),需根据格式调整处理逻辑。
- 性能限制:适合小型项目或快速开发,大型项目建议使用
libpng
/libjpeg-turbo
。
工程中,可快速集成 stb_image
实现图像处理功能,高级用法可参考官方文档或示例代码。