我通常使用Sean Barrett's极简主义图像加载库来读取/写入像素数组,通常是无符号字符的std :: vector,每个像素由4个无符号字符值表示(R 0-255 G 0-255 B 0-255 A 1-255)。
我想知道的是,如果我可以在编译时将一个图像(或更多)嵌入到我的C ++程序中,那么在运行时std :: vector已经填充了像素并且可以使用。那是因为我的应用程序有一堆图像,如果没有另外指定,则用作默认纹理。
我的编译器是MinGW GCC 4.8.2
编辑: 基于到目前为止发布的答案以及我在浏览时发现的其他答案,我想出了这个临时解决方案。
一个小程序,用于将我的图像转换为代码作为字节数组。
convert_file_to_code.cpp
#include <cstdlib>
#include <cstdio>
#include <string>
int main(int argc, char** argv) {
if (argc != 3)
{
printf("f2bytes row file\n");
printf("row = after how many bytes to add a new line (0 for continuous)\n");
printf("file = the name of the input file that should be converted\n");
printf("note: a new file with the same name but .cpp appended will be create as output");
return EXIT_FAILURE;
}
int rowl = atoi(argv[1]);
std::string fsn(argv[2]);
std::string fdn(argv[2]);
fdn.append(".cpp");
FILE* fs = fopen(fsn.c_str(), "rb");
if (!fs)
printf("Failed to open source file %s \n", fsn.c_str());
FILE* fd = fopen(fdn.c_str(), "w");
if (!fd)
printf("Failed to open destination file %s \n", fdn.c_str());
printf("transferring from %s to %s with row length of %d", fsn.c_str(), fdn.c_str(), rowl);
fprintf(fd, "static const unsigned char file_data[] = {");
if (rowl != 0) fprintf(fd, "\n");
int n = 0;
while(!feof(fs)) {
unsigned char c;
if(fread(&c, 1, 1, fs) == 0) break;
fprintf(fd, "0x%.2X,", (int)c);
++n;
if(rowl !=0 && n % rowl == 0) fprintf(fd, "\n");
}
fprintf(fd, "};\n");
fclose(fs);
fclose(fd);
return EXIT_SUCCESS;
}
使用文件数据在运行时将字节数组转换为像素数组的程序。
sample_program.cpp
#include <cstdlib>
#include <cstdio>
#include <string>
#include <vector>
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
static const unsigned char file_data[] = {0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A /* ... more data */};
int width, height, channel;
std::vector<unsigned char> pixel_data;
void read_data()
{
// I know the image is a png data
unsigned char* ptr = stbi_load_from_memory(&file_data[0], sizeof(file_data), &width, &height, &channel, STBI_rgb_alpha);
if (ptr && width && height)
{
// Copy the loaded pixels to the pixel buffer
pixel_data.resize(width * height * 4 /* R+G+B+A */ );
memcpy(&pixel_data[0], ptr, pixel_data.size());
// Free the loaded pixels
stbi_image_free(ptr);
printf("Loaded: %d x %d image \n", width, height);
}
else
{
printf("Failed: %s\n", stbi_failure_reason());
}
}
void write_data(const std::string& file)
{
std::string filename(file);
filename.append(".png");
if (!stbi_write_png(filename.c_str(), width, height, 4, &pixel_data[0], 0))
printf("Could not save %d x %d image to file %s\n", width, height, filename.c_str());
}
int main(void)
{
read_data();
write_data("myimage");
return EXIT_SUCCESS;
}
这就是我到目前为止所得到的。而且BTW图像不需要在编译时替换,所以这个解决方案到目前为止工作。
我猜测在读取像素之后保留file_data []会浪费一些内存,但在读取像素后我会找到一种方法来删除它。
答案 0 :(得分:2)
如果我是你,我会写一些C ++“代码”生成器代码,将图像读入您的数据存储,并用它扩展您现有的源代码。
此程序将预编译并作为构建过程的一部分运行。你也可以在C ++中做到这一点,当然,这些东西通常用脚本语言编写得更好,比如python,因为性能通常不是主要关注点。