stb_image.h图像加载库使用(特别是GIF文件解码)

        stb_image.hSean Barrett的一个非常流行的单头文件图像加载库,它能够加载大部分流行的文件格式,并且能够很简单得整合到你的工程之中。stb_image.h可以在这里下载。下载这一个头文件,将它以stb_image.h的名字加入你的工程,并另创建一个新的C或C++文件,输入以下代码:

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

        通过定义STB_IMAGE_IMPLEMENTATION,预处理器会修改头文件,让其只包含相关的函数定义源码,等于是将这个头文件变为一个源文件了。现在只需要在你的程序中包含stb_image.h并编译就可以了。

        使用stb_image.h加载图片,我们需要使用它的stbi_load函数:

int width, height, nrChannels;
unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);

        这个函数首先接受一个图像文件的位置作为输入。接下来它需要三个int作为它的第二、第三和第四个参数,stb_image.h将会用图像的宽度高度颜色通道的个数填充这三个变量。

        但是对于GIF动画,stbi_load函数只能输出一帧数据。针对GIF动画自己封装了stbi_load_gif函数来获取全部的帧数据。

STBIDEF stbi_uc *stbi_load_gif(char const *filename, int **delays, int *width, int *height, int *frames, int *nrChannels, int req_comp) 
{
    FILE *f = stbi__fopen(filename, "rb");
    unsigned char *result;
    if (!f) return stbi__errpuc("can't fopen", "Unable to open file");
    fseek(f, 0, SEEK_END);
    int bufSize = ftell(f);
    unsigned char *buf = (unsigned char *)malloc(sizeof(unsigned char) * bufSize);
    if (buf) 
    {
        fseek(f, 0, SEEK_SET);
        fread(buf, 1, bufSize, f);
        result = stbi_load_gif_from_memory(buf, bufSize, delays, width, height, frames, nrChannels, req_comp);
        free(buf);
        buf = NULL;
    }
    else 
    {
        result = stbi__errpuc("outofmem", "Out of memory");
    }
    fclose(f);
    return result;
}

        stbi_load_gif函数的使用方法和stbi_load函数类似:

int *delays = NULL, width = 0, height = 0, frames = 1, nrChannels = 0;
delays = (int *)malloc(sizeof(int) * frames);
if (delays) 
{
    delays[0] = 0;
}
unsigned char *data = stbi_load_gif("container.gif", &delays, &width, &height, &frames, &nrChannels, 0);

        delays为一维数组,存放每帧图片播放的延迟时间,第n帧图片延迟时间为delays[n];frames为总帧数;返回值data存放全部的帧数据, 第n帧图片数据位置为data + n * width * height * nrChannels。

        将stbi_load函数和stbi_load_gif函数整合得到stbi_xload函数:

STBIDEF stbi_uc *stbi_xload(char const *filename, int **delays, int *width, int *height, int *frames, int *nrChannels) 
{
    FILE *f = stbi__fopen(filename, "rb");
    unsigned char *result;
    if (!f) return stbi__errpuc("can't fopen", "Unable to open file");
    stbi__context s;
    stbi__start_file(&s, f);
    if (stbi__gif_test(&s)) 
    {
        result = stbi_load_gif(filename, delays, width, height, frames, nrChannels, 0);
    }
    else 
    {
        result = stbi_load(filename, width, height, nrChannels, 0);
    }
    fclose(f);
    return result;
}

参考资料:

https://learnopengl-cn.github.io/01 Getting started/06 Textures/

http://gist.github.com/urraka/685d9a6340b26b830d49

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
使用 stb_image.h 读取材质可以让我们很方便地加载各种格式的图片,这里以 OpenGL 中的纹理为例进行说明。首先需要下载 stb_image.h ,并将其添加到项目中。 使用 stb_image.h 加载纹理的一般步骤如下: 1. 使用 `glGenTextures` 函数生成一个纹理 ID。 2. 使用 `glBindTexture` 函数将纹理 ID 绑定到目标纹理类型上,例如 `GL_TEXTURE_2D`。 3. 使用 `stbi_load` 函数加载图片数据,并获取图片的宽度、高度和颜色通道数。 4. 使用 `glTexImage2D` 函数将图片数据传递给 OpenGL,生成纹理。 5. 使用 `glTexParameteri` 函数设置纹理的参数,例如过滤方式和环绕方式。 6. 释放图片数据。 加载纹理的代码示例如下: ```c++ // 读取图片 int width, height, nrChannels; unsigned char *data = stbi_load("texture.jpg", &width, &height, &nrChannels, 0); // 创建纹理对象 unsigned int texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); // 设置纹理参数 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 生成纹理 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); // 释放图片数据 stbi_image_free(data); ``` 注意:在使用 stb_image.h 加载纹理时,需要将图片的 y 轴翻转,否则加载出来的纹理会是倒置的。可以通过设置 `stbi_set_flip_vertically_on_load(true)` 来实现自动翻转。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值