STB:简化 C、C++ 开发的单头文件库集合

2025-03-03 11:41:22

STB(Single-File Libraries)是一系列单头文件库的集合,旨在简化 C/C++ 开发过程。这些库涵盖了图形处理、音频处理、图像处理等多个领域,提供了丰富的功能和高效的实现。本文将详细介绍 STB 的功能、使用方法、常见库以及使用场景。

STB 简介

STB 是一系列单头文件库的集合,由 Sean Barrett 开发和维护。这些库的特点是每个库仅包含一个头文件,用户只需将头文件包含到项目中即可使用库中的功能。STB 库的设计目标是简单、高效和易于集成,使得开发者能够快速上手并实现所需的功能。

功能概述

STB 库集合提供了多种功能,涵盖了图形处理、音频处理、图像处理等多个领域。以下是其主要功能:

  1. 图像处理:提供图像加载、保存、缩放、旋转等功能。
  2. 音频处理:提供音频解码、播放等功能。
  3. 字体渲染:提供字体加载、渲染等功能。
  4. 图形渲染:提供基本的图形渲染功能。
  5. 文件系统:提供文件系统操作功能。
  6. 数学库:提供基本的数学运算功能。

使用方法

使用 STB 库非常简单,以下是基本步骤:

  1. 下载库文件:从 STB 的 GitHub 仓库下载所需的头文件。
  2. 包含头文件:在项目中包含相应的头文件。
  3. 调用函数:使用头文件中提供的函数实现所需的功能。

下载库文件

STB 库的源代码托管在 GitHub 上,可以通过以下命令下载:

git clone https://github.com/nothings/stb.git

包含头文件

在项目中包含相应的头文件。例如,使用 stb_image.h 库加载图像文件:

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

调用函数

使用头文件中提供的函数实现所需的功能。例如,使用 stb_image.h 库加载图像文件:

#include <stdio.h>
#include "stb_image.h"

int main() {
    int width, height, channels;
    unsigned char *img = stbi_load("image.png", &width, &height, &channels, 0);
    if (img == NULL) {
        printf("Failed to load image\n");
        return 1;
    }
    printf("Loaded image with a width of %dpx, a height of %dpx and %d channels\n", width, height, channels);
    stbi_image_free(img);
    return 0;
}

常见库

STB 库集合包含多个常用的单头文件库,以下是其中一些常见的库:

图像处理

stb_image.h 是一个用于加载和保存图像的库,支持多种图像格式,如 PNG、JPEG、BMP 等。

使用示例:

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

int main() {
    int width, height, channels;
    unsigned char *img = stbi_load("image.png", &width, &height, &channels, 0);
    if (img == NULL) {
        printf("Failed to load image\n");
        return 1;
    }
    printf("Loaded image with a width of %dpx, a height of %dpx and %d channels\n", width, height, channels);
    stbi_image_free(img);
    return 0;
}

音频处理

stb_vorbis.h 是一个用于解码 Vorbis 音频文件的库。

使用示例:

#define STB_VORBIS_HEADER_ONLY
#include "stb_vorbis.c"

int main() {
    int error;
    stb_vorbis *v = stb_vorbis_open_filename("audio.ogg", &error, NULL);
    if (v == NULL) {
        printf("Failed to open audio file\n");
        return 1;
    }
    int channels = stb_vorbis_get_info(v)->channels;
    printf("Audio file has %d channels\n", channels);
    stb_vorbis_close(v);
    return 0;
}

字体渲染

stb_truetype.h 是一个用于加载和渲染 TrueType 字体的库。

使用示例:

#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"

int main() {
    unsigned char ttf_buffer[1<<20];
    unsigned char temp_bitmap[512*512];
    FILE *f = fopen("font.ttf", "rb");
    fread(ttf_buffer, 1, 1<<20, f);
    fclose(f);

    stbtt_fontinfo font;
    stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));

    float scale = stbtt_ScaleForPixelHeight(&font, 15);
    int ascent, descent, lineGap;
    stbtt_GetFontVMetrics(&font, &ascent, &descent, &lineGap);

    int baseline = (int) (ascent * scale);
    int num_rows = baseline + (int)(-descent * scale);
    int pen_y = num_rows - baseline;

    int bitmap_w = 512;
    int bitmap_h = num_rows;
    stbtt_BakeFontBitmap(ttf_buffer, 0, 15.0, temp_bitmap, bitmap_w, bitmap_h, 32, 96, cdata);

    int x0, y0, x1, y1;
    stbtt_GetCodepointBitmapBox(&font, 'x', scale, scale, &x0, &y0, &x1, &y1);
    int advance, lsb;
    stbtt_GetCodepointHMetrics(&font, 'x', &advance, &lsb);
    float x_shift = x0 + lsb * scale;
    float y_shift = y0;

    int x = 32 - (int) x_shift;
    int y = pen_y + (int) y_shift;

    stbtt_MakeCodepointBitmap(&font, temp_bitmap + x + y * bitmap_w, x1 - x0, y1 - y0, bitmap_w, scale, scale, 'x');

    return 0;
}

图形渲染

stb_rect_pack.h 是一个用于矩形打包的库,适用于纹理打包等场景。

使用示例:

#define STB_RECT_PACK_IMPLEMENTATION
#include "stb_rect_pack.h"

int main() {
    stbrp_context context;
    stbrp_node nodes[1024];
    stbrp_init_target(&context, 512, 512, nodes, 1024);

    stbrp_rect rects[4];
    rects[0].id = 0; rects[0].w = 100; rects[0].h = 100;
    rects[1].id = 1; rects[1].w = 200; rects[1].h = 50;
    rects[2].id = 2; rects[2].w = 50; rects[2].h = 200;
    rects[3].id = 3; rects[3].w = 150; rects[3].h = 150;

    stbrp_pack_rects(&context, rects, 4);

    for (int i = 0; i < 4; i++) {
        if (rects[i].was_packed) {
            printf("Rect %d packed at (%d, %d)\n", rects[i].id, rects[i].x, rects[i].y);
        } else {
            printf("Rect %d not packed\n", rects[i].id);
        }
    }

    return 0;
}

文件系统

stb_filesystem.h 是一个用于文件系统操作的库,提供文件读取、写入等功能。

使用示例:

#define STB_FILESYSTEM_IMPLEMENTATION
#include "stb_filesystem.h"

int main() {
    char buffer[1024];
    int size = stb_filesystem_read_file("file.txt", buffer, sizeof(buffer));
    if (size > 0) {
        printf("File content:\n%s\n", buffer);
    } else {
        printf("Failed to read file\n");
    }
    return 0;
}

数学库

stb_math.h 是一个用于基本数学运算的库,提供向量、矩阵等操作。

使用示例:

#define STB_MATH_IMPLEMENTATION
#include "stb_math.h"

int main() {
    stb_vec3 v1 = {1.0f, 2.0f, 3.0f};
    stb_vec3 v2 = {4.0f, 5.0f, 6.0f};
    stb_vec3 v3 = stb_vec3_add(v1, v2);
    printf("v3 = (%f, %f, %f)\n", v3.x, v3.y, v3.z);
    return 0;
}

使用场景

STB 库集合适用于多种使用场景,以下是一些常见的使用场景:

  1. 游戏开发:游戏开发者可以使用 STB 库进行图像加载、音频解码、字体渲染等操作。
  2. 图形应用:图形应用开发者可以使用 STB 库进行图像处理、纹理打包等操作。
  3. 嵌入式系统:嵌入式系统开发者可以使用 STB 库进行文件系统操作、基本数学运算等操作。
  4. 教育和研究:教育和研究开发者可以使用 STB 库进行图像处理、音频处理等操作。

总结

STB 是一个功能强大的单头文件库集合,旨在简化 C/C++ 开发过程。通过其丰富的功能和高效的实现,STB 库能够显著提高开发效率和代码质量。无论是游戏开发、图形应用、嵌入式系统还是教育和研究,STB 库都能提供可靠的解决方案。通过本文的详细介绍,希望读者能够更好地理解和使用 STB 库,提升 C/C++ 开发的体验和效率。

nothings
stb 是一个小巧的的C/C++ 库,每个头文件可以单独使用,头文件中包含了函数的实现。主要包含一些音频和图像相关的库。
C
Other
28.1 k