GitHub上有个开源的stb库,Star数已过万,地址为https://github.com/nothings/stb,为何叫stb,是用的作者名字的缩写Sean T. Barrett。此库仅包含头文件,除stretchy_buffer.h外,其它所有文件以前缀stb开头,每个头文件的作用及用法在每个头文件的开始部分都作了介绍。此开源库的license为public domain或MIT。下面仅对与图像相关的头文件的作用及使用进行简单的说明,当仅需要将图像数据载入内存、或进行缩放操作、或保存图像时使用stb会非常方便,因为仅需要include一个或三个头文件即可,不需要额外图像处理库的依赖,如libjpeg、libpng、opencv等:
1. stb_image.h:载入图像,支持的图像文件格式包括JPEG、PNG、TGA、BMP、PSD、GIF、HDR、PIC、PNM,使用到的函数主要为:stbi_load,参数依次为:图像文件名(filename),获取图像宽(x),获取图像高(x),获取图像通道数(channels_in_file)、指定期望的通道数(desired_channels,若为0则不做颜色空间变换),此函数正常返回图像数据指针,否则返回NULL;
2. stb_image_resize.h:图像缩放,使用到的函数主要为stbir_resize_uint8,参数依次为:输入图像数据指针(input_pixels)、输入图像宽(input_w)、输入图像高(input_h)、输入图像步长(input_stride_in_bytes,若为0则为宽x通道数)、输出图像数据指针(output_pixels)、输出图像宽(output_w)、输出图像高(output_h)、输出图像步长(output_stride_in_bytes,若为0则为宽*通道数)、图像通道数(num_channels,输入与输出一致),此函数正常返回1,否则返回0;
3. stb_image_write.h:保存图像,支持的图像文件格式包括PNG、BMP、TGA、JPG、HDR,使用到的函数主要为stbi_write_xxx,其中xxx可以为png、bmp、tga、hdr、jpg,参数依次为:保存图像名(filename)、图像宽(w)、图像高(h)、图像通道数(comp)、图像数据指针(data),步长(stride_in_bytes,若为0则为宽*通道数,仅限png)、图像质量(quality,取值范围1~100,仅限jpg),此函数正常返回非0值,否则返回0。
以下为测试代码(test_stb.cpp):
#include "funset.hpp"
#include
#include
#include
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#define STB_IMAGE_RESIZE_STATIC
#include "stb_image_resize.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define STB_IMAGE_WRITE_STATIC
#include "stb_image_write.h"
int test_stb_image()
{
#ifdef _MSC_VER
const std::string files_path {"E:/GitCode/OCR_Test/test_data/"};
#else
const std::string files_path {"test_data/"};
#endif
const std::vector images_name{"marge.jpg", "lena.png"};
for (auto name : images_name) {
const std::string image = files_path + name;
// load image
int x, y, channels_in_file, desired_channels = 3;
unsigned char* data = stbi_load(image.c_str(), &x, &y, &channels_in_file, desired_channels);
if (!data) {
fprintf(stderr, "fail to read image: %s\n", image.c_str());
return -1;
}
fprintf(stdout, "image: %s, x: %d, y: %d, channels_in_file: %d, desired_channels: %d\n", name.c_str(), x, y, channels_in_file, desired_channels);
// resize image
int width_resize = x * 1.5, height_resize = y * 1.4;
unsigned char* output_pixels = (unsigned char*)malloc(width_resize * height_resize * desired_channels);
int ret = stbir_resize_uint8(data, x, y, 0, output_pixels, width_resize, height_resize, 0, desired_channels);
if (ret == 0) {
fprintf(stderr, "fail to resize image: %s\n", image.c_str());
return -1;
}
// write(save) image
const std::string save_name_png = image + ".png";
const std::string save_name_jpg = image + ".jpg";
ret = stbi_write_png(save_name_png.c_str(), width_resize, height_resize, desired_channels, output_pixels, 0);
if (ret == 0) {
fprintf(stderr, "fail to write image png: %s\n", image.c_str());
return -1;
}
ret = stbi_write_jpg(save_name_jpg.c_str(), width_resize, height_resize, desired_channels, output_pixels, 90);
if (ret == 0) {
fprintf(stderr, "fail to write image jpg: %s\n", image.c_str());
return -1;
}
free(data);
free(output_pixels);
}
return 0;
}
执行结果如下图所示:
GitHub:https://github.com/fengbingchun/OCR_Test