C ++在编译时将图像像素嵌入向量中?

时间:2014-02-25 06:42:01

标签: c++ vector

我通常使用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 []会浪费一些内存,但在读取像素后我会找到一种方法来删除它。

1 个答案:

答案 0 :(得分:2)

如果我是你,我会写一些C ++“代码”生成器代码,将图像读入您的数据存储,并用它扩展您现有的源代码。

此程序将预编译并作为构建过程的一部分运行。你也可以在C ++中做到这一点,当然,这些东西通常用脚本语言编写得更好,比如python,因为性能通常不是主要关注点。