一. stb_image 简介

stb_image.h

stb_image.h 是 Sean Barrett 的一个非常流行的单头文件图像加载库,它能够读写大部分流行的文件格式,支持文件格式如下:

  • png
  • jpg
  • tga
  • bmp
  • psd
  • gif
  • hdr
  • pic

格式虽多,不过一般用到 png 和 jpg 就好了。
除了从文件加载图片,stb_image 还支持从内存中加载图片,通过该方法 stbi_load_from_memory,在后续文章中会用到它的。
加载完图片之后,stb_image 还提供了相应的释放方法 stbi_image_free,实际上就是把 free 封装了一下而已。

作者

作者: Sean Barrett
博客地址: http://nothings.org/

Sean Barrett 1998 照片

重点关注如下三个头文件:

  • stb_image.h
    用于图像加载
  • stb_image_write.h
    用于写入图像文件
  • stb_image_resize.h
    用于改变图像尺寸

二. stb_image 添加到工程的方法

stb_image.h 官网下载地址: https://github.com/nothings/stb

在我们的 C 或 C++ 文件中需要以下面的形式添加 stb_image.h 头文件 使其生效:

//您可以在 #include 之前定义 #define STBI_ASSERT(x) 以避免使用 assert.h 头文件。
//定义 #define STBI_MALLOC,STBI_REALLOC 和 STBI_FREE 宏可以避免使用 malloc,realloc,free 函数。
#define STB_IMAGE_IMPLEMENTATION  //必须加上
#include "stb_image.h"

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

三. stb_image 读取

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

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C/C++ 使用 stb_image 加载 png / jpg / gif / bmp等常用图片
//@Time:2022/03/28 07:30
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 


#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

/*
* 描述:载入图像,支持的图像文件格式包括JPEG、PNG、TGA、BMP、PSD、GIF、HDR、PIC、PNM
* 参数:
*   filename:图像文件名
*   x:获取图像宽
*   y:获取图像高
*   channels_in_file:获取图像通道数
*   desired_channels:指定期望的通道数,若为0则不做颜色空间变换
* 返回值:
*    加载图像成功返回图像数据指针,否则返回NULL;
*/
unsigned char *stbi_load            (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);

其中参数 desired_channels 就代表图片的颜色通道值,通常有如下的情况:
0 :则不做颜色空间变换
1 : 灰度图
2 : 灰度图加透明度
3 : 红绿蓝 RGB 三色图
4 : 红绿蓝加透明度 RGBA 图

四. stb_image 写入

stb_image 可以分别支持生产 png 和 jpg,函数声明如下

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C/C++ 使用 stb_image 加载 png / jpg / gif / bmp等常用图片
//@Time:2022/03/28 07:30
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 


#define STB_IMAGE_WRITE_IMPLEMENTATION
#define STB_IMAGE_WRITE_STATIC
#include "stb_image_write.h"

/*
* 描述:保存图像,支持的图像文件格式包括PNG、BMP、TGA、JPG、HDR
* 
* 参数:
*   filename:保存图像名
*   x:图像宽
*   y:图像高
*   comp:图像通道数
*   data:指定期望的通道数,若为0则不做颜色空间变换
*   quality:图像质量(quality,取值范围1~100,仅限jpg)
*
* 返回值:成功返回非0值,否则返回0。
*/
int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality)



/*
* 描述:保存图像,支持的图像文件格式包括PNG、BMP、TGA、JPG、HDR
* 
* 参数:
*   filename:保存图像名
*   x:图像宽
*   y:图像高
*   comp:图像通道数
*   data:指定期望的通道数,若为0则不做颜色空间变换
*   stride_bytes:步长,若为0则为宽*通道数,仅限png
*
* 返回值:成功返回非0值,否则返回0。
*/
int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)

五.stb_image 缩放

stb_image 缩放函数如下:

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C/C++ 使用 stb_image 加载 png / jpg / gif / bmp等常用图片
//@Time:2022/03/28 07:30
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 

#define STB_IMAGE_RESIZE_IMPLEMENTATION
#define STB_IMAGE_RESIZE_STATIC
#include "stb_image_resize.h"


/*
* 描述:图像缩放
* 
* 参数:
*   input_pixels:输入图像数据指针
*   input_w:输入图像宽
*   input_h:输入图像高
*   input_stride_in_bytes:输入图像步长,若为0则为宽x通道数
*   output_pixels:输出图像数据指针
*   output_w:输出图像宽
*   output_h:输出图像高
*   output_stride_in_bytes:输出图像步长,若为0则为宽x通道数
*   num_channels:图像通道数,输入与输出一致
*
* 返回值:成功返回1,否则返回0;
*/
int stbir_resize(const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes,void *output_pixels, int output_w, int output_h, int output_stride_in_bytes,stbir_datatype datatype,int num_channels, int alpha_channel, int flags,stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical,stbir_filter filter_horizontal,  stbir_filter filter_vertical,stbir_colorspace space, void *alloc_context);

六. stb_image 内存释放

stb_image 释放内存如下:

void     stbi_image_free      (void *retval_from_stbi_load);

七. stb_image 使用案例

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C/C++ 使用 stb_image 加载 png / jpg / gif / bmp等常用图片
//@Time:2022/03/28 07:30
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/ 

#include <iostream>

 #define STB_IMAGE_IMPLEMENTATION
 #include "stb_image.h"
 #define STB_IMAGE_WRITE_IMPLEMENTATION
 #include "stb_image_write.h"
 #define STB_IMAGE_RESIZE_IMPLEMENTATION
 #include "stb_image_resize.h"
 #include <string>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

using namespace std;

int main() {
    std::cout << "Hello, STB_Image" << std::endl;

    string inputPath = "d://input.png";
    int iw, ih, n;

    // 加载图片获取宽、高、颜色通道信息
    unsigned char *idata = stbi_load(inputPath.c_str(), &iw, &ih, &n, 0);

    int ow = iw / 2;
    int oh = ih / 2;
    auto *odata = (unsigned char *) malloc(ow * oh * n);

    // 改变图片尺寸
    stbir_resize(idata, iw, ih, 0, odata, ow, oh, 0, STBIR_TYPE_UINT8, n, STBIR_ALPHA_CHANNEL_NONE, 0,
                 STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP,
                 STBIR_FILTER_BOX, STBIR_FILTER_BOX,
                 STBIR_COLORSPACE_SRGB, nullptr
    );

    string outputPath = "d://output.png";
    // 写入图片
    stbi_write_png(outputPath.c_str(), ow, oh, n, odata, 0);

    stbi_image_free(idata);
    stbi_image_free(odata);
    return 0;
}

八. stb_image 完整代码下载

源码下载地址:https://github.com/nothings/stb


来源: