如何将图像中的每个像素作为16位索引存储到可输入的?

时间:2013-12-05 08:32:28

标签: c++ c qt image-processing

我有一个浮点值的二维数组:

float values[1024][1024];

我想将其存储为图像。

值在以下范围内:[ - 范围,+范围]。

我想使用从红色( - 范围)到白色(0)到黑色(+范围)的colortable。

到目前为止,我一直使用BMP文件格式将每个像素存储为32位RGBA。用于存储我的阵列的总内存是1024 * 1024 * 4字节= 4MB。

这似乎非常有用,因为我知道我的colortable是“1维”,而32 RGBA是“4维”。

看看我的意思;假设我的colortable从黑色( - 范围)变为蓝色(+范围)。 在这种情况下,唯一变化的组件显然是B,所有其他组件都是固定的。 所以我只获得8位精度而我正在“支付”32: - (。

因此,我正在寻找基于“调色板”的文件格式。 理想情况下,我希望每个像素都是一个16位索引(无符号短整数),成为由2 ^ 16个RGBA值组成的“调色板”。 在这种情况下,用于存储我的阵列的总内存将是:1024 * 1024 * 2字节+ 2 ^ 16 * 4bytes = 2.25 MB。 因此,几乎一半的“价格”,我的精确度会提高两倍!

哪种图片格式支持此功能?

目前我正在使用Qt的QImage将数组写入文件作为图像。 QImage具有内部8位索引(“调色板”)格式。我想要一个16位的。另外,我从Qt的文档中不了解哪种文件格式支持8位索引内部格式。

3 个答案:

答案 0 :(得分:2)

将其存储为16位灰度PNG并自行手动执行颜色表。

你没有说为什么你的图像可以用2 ^ 16种颜色分解,但是使用你对这个特殊图像的了解,你可以制作一个算法,使得彼此接近的索引具有相似的颜色,因此更容易压缩。

答案 1 :(得分:1)

PNG format支持最多8位的调色板格式,但也应支持最高16位的灰度图像。但是,16位模式使用较少,可能缺乏软件支持。你应该先测试你的工具。

但您也可以使用普通的24位RGB真彩色PNG图像进行测试。它们是压缩的,在任何情况下都应该比BMP产生更好的结果。

答案 2 :(得分:1)

“我想使用从红色( - 范围)到白色(0)到黑色(+范围)的colortable。”

好的,所以你有FF,00,00(红色)到FF,FF,FF(白色)到00,00,00(黑色)。在24位RGB中,我看起来像从红色到白色的256个值,然后是从白色到黑色的256个值。所以你不需要调色板大小2 ^ 16(16384);你需要2 ^ 9(512)。

如果您愿意妥协并使用2 ^ 8的调色板大小,则GIF格式可以正常工作。这仍然是相对精细的分辨率:负片尺寸上有128种红色阴影,正面上有128种灰度阴影。每个GIF的256个调色板条目都可以是RGB值。

PNG是基于调色板的颜色的另一个候选者。如果你需要一个alpha通道,你可以更灵活地使用PNG,包括RGBA。

您在提问中提到了RGBA,但没有解释使用Alpha通道。

如此独立于文件格式,如果您可以使用256条目调色板,那么您将拥有一个非常好的压缩图像。回到你的映射要求(即将浮点数[-range - > 0.0 - > +范围]映射到[red - > white - > black],这里是一个256条目调色板,涵盖范围红 - 白 - 黑你想要的:

float    entry#  color  rgb
------  -------  -----  --------
-range    0  00  red    FF,00,00
          1  01         FF,02,02
          2  02         FF,04,04
             ...          ...
             ...          ...
        127  7F         FF,FD,FD
  0.0   128  80  white  FF,FF,FF
        129  81         FD,FD,FD
             ...          ....
             ...          ...
        253  FD         04,04,04
        254  FE         02,02,02
+range  255  FF  black  00,00,00

如果将颜色表的大小加倍为9位(512个值),则可以使RGB条目之间的增量更精细:增量为1而不是2.这样的9位调色板可以为您提供完整的单个 - 范围的负侧和正侧的RGB信道分辨率。目前尚不清楚,根据您想要的映射,分配16位调色板真的能够存储更多的视觉信息。我希望我理解你的问题,也许这很有用。