存储未压缩RGBA图像数据的最简单格式

时间:2017-04-22 18:05:22

标签: c image format rgba

我目前正在创建一个软件工具,可以为每个像素生成包含独立RGBA信息的图像 - 这意味着红色,绿色,蓝色和 alpha 组件应该被读取并视为单独的实体在单个像素中(即没有alpha预乘或任何其他数据组合技巧)。

这些图像必须存储在磁盘上。目的是以一种方式存储它们,以后可以通过简单的C程序一次一个像素地容易地读取图像的各种像素。另一个要求是存储的图像本身应至少由一个OS工具可见(适用于MacOS的预览,适用于Windows的Paint,Web浏览器或任何其他常用工具,以便在计算机中查看图像)。

如上所述,我可以用来存储数据的最简单的图像文件格式是什么?我发现的最接近的是TIFF;但是,该规范要求对RGBA值进行alpha预乘。您知道哪些其他格式让我以未压缩的RGBA普通格式存储图像数据?

为了清楚起见,文件大小是一个问题。像素中的组件的顺序也不是问题; BGRA在此项目中与所有实际用途一样有效。

2 个答案:

答案 0 :(得分:2)

好的,回答我自己的问题。显然,答案是,"我看起来不够努力" :D。

在关于 BMP 图像文件格式的Wikipedia article中,有一个4x2 ARGB图像的示例,其中的所有字段都已清楚说明。

谢谢,@ Weather Vane提示。

但是,我确实发现其中的数据存在问题。对于MacOS的预览并不喜欢该特定图像,具有该特定格式。我对该文件进行了一些更改,并成功生成了一个可在MacOS和Windows上查看和使用的4x2 ARGB位图。

以下是我用于生成BMP文件的代码,供将来参考:

#include <iostream>
#include <fstream>

unsigned char bmpData[] = // All values are little-endian
{
    0x42, 0x4D,             // Signature 'BM'
    0xaa, 0x00, 0x00, 0x00, // Size: 170 bytes
    0x00, 0x00,             // Unused
    0x00, 0x00,             // Unused
    0x8a, 0x00, 0x00, 0x00, // Offset to image data

    0x7c, 0x00, 0x00, 0x00, // DIB header size (124 bytes)
    0x04, 0x00, 0x00, 0x00, // Width (4px)
    0x02, 0x00, 0x00, 0x00, // Height (2px)
    0x01, 0x00,             // Planes (1)
    0x20, 0x00,             // Bits per pixel (32)
    0x03, 0x00, 0x00, 0x00, // Format (bitfield = use bitfields | no compression)
    0x20, 0x00, 0x00, 0x00, // Image raw size (32 bytes)
    0x13, 0x0B, 0x00, 0x00, // Horizontal print resolution (2835 = 72dpi * 39.3701)
    0x13, 0x0B, 0x00, 0x00, // Vertical print resolution (2835 = 72dpi * 39.3701)
    0x00, 0x00, 0x00, 0x00, // Colors in palette (none)
    0x00, 0x00, 0x00, 0x00, // Important colors (0 = all)
    0x00, 0x00, 0xFF, 0x00, // R bitmask (00FF0000)
    0x00, 0xFF, 0x00, 0x00, // G bitmask (0000FF00)
    0xFF, 0x00, 0x00, 0x00, // B bitmask (000000FF)
    0x00, 0x00, 0x00, 0xFF, // A bitmask (FF000000)
    0x42, 0x47, 0x52, 0x73, // sRGB color space
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Unused R, G, B entries for color space
    0x00, 0x00, 0x00, 0x00, // Unused Gamma X entry for color space
    0x00, 0x00, 0x00, 0x00, // Unused Gamma Y entry for color space
    0x00, 0x00, 0x00, 0x00, // Unused Gamma Z entry for color space

    0x00, 0x00, 0x00, 0x00, // Unknown
    0x00, 0x00, 0x00, 0x00, // Unknown
    0x00, 0x00, 0x00, 0x00, // Unknown
    0x00, 0x00, 0x00, 0x00, // Unknown

    // Image data:
    0xFF, 0x00, 0x00, 0x7F, // Bottom left pixel
    0x00, 0xFF, 0x00, 0x7F,
    0x00, 0x00, 0xFF, 0x7F,
    0xFF, 0xFF, 0xFF, 0x7F, // Bottom right pixel
    0xFF, 0x00, 0x00, 0xFF, // Top left pixel
    0x00, 0xFF, 0x00, 0xFF,
    0x00, 0x00, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF  // Top right pixel
};

int main(int argc, const char * argv[])
{
    std::fstream fs("test.bmp", std::ios_base::out | std::ios_base::binary);

    fs.write((const char *)bmpData, sizeof(bmpData));

    fs.close();

    std::cout << "The BMP has been written.\n";

    return 0;
}

答案 1 :(得分:0)

我知道RGBA BMP已经解决了这个问题,但是还有另一种选择:Netpbm员工创建了一种新格式来扩展PBM / PGM / PPM / PNM,它还可以存储16位深度和/或Alpha通道。

它称为便携式任意地图,并使用.pam扩展名。除了具有P7魔术标头编号和稍微扩展的标头格式外,它的功能与其他二进制PNM格式相似。例如,要创建一个4px x 2px的RGBA图像,每个通道具有8bpp,则可以使用以下标头:

P7
WIDTH 4
HEIGHT 2
DEPTH 4
MAXVAL 255
TUPLTYPE RGB_ALPHA
ENDHDR

...之后是对像素数据进行平整转储。

您可以在Netpbm页面上查看更多详细信息:http://netpbm.sourceforge.net/doc/pam.html

当前.pam不受广泛支持,因此缺少您的关键问题(“必须使用内置的OS工具才能查看”)。 XnView和FFmpeg至少可以使用它。另外,Netpbm库附带了一个pamtopng实用程序,该实用程序的功能与锡上所说的完全一样-甚至将RGBA PAM转换为带有alpha的PNG。因此,如果您正在编写自己的工具,则可以将其视为一种交换格式。