将十六进制数据(RGB888)中的图像文件转换为BMP,JPG,PNG或其他格式

时间:2018-12-11 13:16:27

标签: c++ image hex rgb

我遇到了以下问题,我在其中放入了图像文件(假设是RGB888),但是我不确定这是否真的是这种数据。 (我只知道数据的假定格式(例如400 * 600),这就是为什么我制作图片的样本数据时,我确切地知道十六进制数据的格式的原因。)

我创建的数据如下所示:

0xf3, 0x8d, 0x4c, 0xff, 0xf2, 0x8f, 0x4b, 0xff, 0xef, ...

在这种情况下,我确定这是RGB888,因为我对其进行了转换。 因此,我要做的第一步是加载文件并将数据流式传输到char数组。

std::ifstream infile;
char *array;
uint8_t *pixelValues;

infile.exceptions ( std::ifstream::failbit );
try {
  infile.open(filename, std::ios_base::binary); 
    infile >> std::hex >> std::setw(2) >> std::setfill('0');  
    int length;

    if (!infile.bad()) {
        length = infile.rdbuf()->pubseekoff(0, std::ios_base::end);
        array = new char[length];
        infile.rdbuf()->pubseekoff(0, std::ios_base::beg);
        infile.read(array, length);
        infile.close();
    }

    uint8_t value;
    pixelValues = new uint8_t[length/5];

    std::size_t counter = 0;
    std::size_t valueCounter = 0;

    while (true) {              
        value = strtol(&array[counter], NULL, 0);
        pixelValues[valueCounter++] = value;

        while ((array[counter] != ',')) counter++;  
        counter++;
        if (counter >= length) break;
    }
}

此步骤之后,uint8_t pixelValues中的数据应为文件中数据的位数组。

我现在的问题是,如何继续...我在做正确的事情吗?或者是否有“更智能”的方法来从十六进制数据中获取图像?

我的同事告诉我,我应该使用openCV继续下一步,但是我根本无法运行它。

如果你们有一个聪明的主意,请让我知道;-)

1 个答案:

答案 0 :(得分:2)

检查某人给您的原始图像并说它是400x600像素RGB888的第一件事是查看文件大小,看是否为:

400 * 600 * 3

个字节,您可以很容易地检查它们,然后再消失,从而使您对格式和内容有误解。那么,您的文件正好是720,000字节吗?


如果您想要最简单的方式来获取PNG或JPEG,只需在终端/命令提示符的命令行中使用 ImageMagick 。因此,如果宽度为400像素,高度为600像素,并且为RGB888,则可以执行以下操作来获取PNG文件:

magick -depth 8 -size 400x600 RGB:YourFile.dat result.png

如果要使用JPEG,请使用:

magick -depth 8 -size 400x600 RGB:YourFile.dat result.jpg

如果您不想安装 ImageMagick ,则可以在Terminal中的文件开头放置一个NetPBM PPM标头,如下所示:

printf "P6\n400 600\n255\n"  >  result.ppm
cat YourImage.dat            >> result.ppm

然后,您将拥有一个文件,该文件可以 Photoshop GIMP feh和许多其他程序读取并另存为PNG或JPG。当然,您可以在3行C ++中完成完全相同的操作。


如果没有一个吸引您的对象,则可以使用CImg-一个精巧,易于使用的精巧C ++图像处理库。有关示例,请参见here