stb_image.h
是Sean Barrett的一个非常流行的单头文件图像加载库,它能够加载大部分流行的文件格式,并且能够很简单得整合到你的工程之中。stb_image.h
可以在这里下载。下载这一个头文件,将它以stb_image.h
的名字加入你的工程,并另创建一个新的C++文件,输入以下代码:
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
通过定义STB_IMAGE_IMPLEMENTATION,预处理器会修改头文件,让其只包含相关的函数定义源码,等于是将这个头文件变为一个 .cpp
文件了。现在只需要在你的程序中包含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);
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/