轻量级单文件图像解码库 - stb_image 开源库

发布于:2025-04-19 ⋅ 阅读:(23) ⋅ 点赞:(0)

轻量级单文件图像解码库 - stb_image 开源库

一. 库简介

stb_image 是一个轻量级的单文件图像解码库,由 Sean T. Barrett 开发,支持多种常见图像格式(如 JPEG、PNG、BMP、GIF、HDR 等),具有以下特点:

  • 单文件实现:仅需包含 stb_image.h 头文件即可使用,无需编译库或复杂配置。
  • 跨平台:支持 Windows、Linux、macOS 等系统。
  • 简单接口:提供 stbi_loadstbi_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 配置项目
  1. 添加头文件:将 stb_image.h 复制到项目目录,或设置头文件路径(如通过 IDE 的附加包含目录)。
  2. 启用实现:在代码中仅一个源文件内定义宏 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_pngstbi_write_jpg)。

六. 常见问题

  • 图像通道顺序:RGB(默认)或 BGR(如 BMP),需根据格式调整处理逻辑。
  • 性能限制:适合小型项目或快速开发,大型项目建议使用 libpng/libjpeg-turbo

工程中,可快速集成 stb_image 实现图像处理功能,高级用法可参考官方文档或示例代码。


网站公告

今日签到

点亮在社区的每一天
去签到