从WIC图像c ++获取RGB

时间:2013-07-12 00:02:30

标签: c++ visual-c++ graphics 2d wic

我正在使用WIC加载图像,然后我希望能够获得每个像素的RGB值。我已经使用 getDataPointer()来创建一个字节缓冲区(我转换为 COLORREF 数组)但是在这之后得到的东西得到了奇怪。

我正在测试一个10x10 24bit的png。如果我查看大小 getDataPointer()给我说它是300,这是有道理的,因为10 * 10 * 3(每像素3个字节)= 300。如果我 getStride()它会给我30,这也是有道理的。

所以我创建了一个循环来通过 COLORREF 和迭代器,条件是 i< size / 3 因为我知道数组中只有100个像素。然后我使用宏 GetRValue() GetGValue() GetBValue()来获取rgb值。

这就是事情变得奇怪 - 我的小图像只是一个测试图像,其中包含纯红色,绿色,蓝色和黑色像素,但我的RGB值出来(255,0,0),(0,255,0) ),(27,255,36),(0,0,0)等似乎某些值不正确并且以某种方式被破坏。此外,图像的最后20/30像素要么是疯狂的颜色,要么是全黑的,这让我觉得有些腐败。

我还用一张更大的实际照片对它进行了测试,它出现了所有灰度并重复相同的模式,让我认为这是一个跨步问题,但我不明白是怎么回事,因为我打电话给 getPixelFormat() WIC表示它是24bppBGR或24bppRGB,具体取决于图像。

有谁知道我做错了什么?我不应该使用COLORREF和宏或类似的东西吗?

感谢您的时间。

修改

嗯,我在这里仍然遇到问题。我尝试使用PixelFormat()报告为24bppBGR的另一个24位PNG,但看起来大步是因为它正在歪斜(强制性的nyan cat测试):

Test WIC load with nyan cat but the stride is off

编辑2

好的,现在看来我有一些工作,有些则没有。有些人报告自己是24bpp BGR工作,而其他人看起来像上面的图像,如果我计算它的步幅,它给我与它应该是什么不同,并且缓冲区的大小也不同。我也有一些32bpp的BGR图像,其中一些是有效的,有些则没有。我在这里错过了什么吗?什么可以组成缓冲区中的额外字节?

以下是一个示例图片:

24bppBGR JPEG:

width = 126
height = 79
buffer size = 30018
stride = 380

如果我算这个:

buffer size should be: width * height * 3 = 126 * 79 * 3 = 29862
difference between calculation and actual buffer size: 30018 - 29862 = 156 bytes

stride size should be: width * 3 = 378
difference between calculation and actual buffer size: 380 - 378 = 2 bytes

I was thinking that we had 2 extra bytes per line but 79 * 2 is 158 not 156 hmm.

如果我对迄今为止工作的图像进行这些计算,我发现计算和代码给我的值没有区别......

我理解这里发生的事情是错的吗?这些计算现在应该按照我的想法运作吗?

再次感谢

1 个答案:

答案 0 :(得分:3)

您不应该使用COLORREF和相关的宏。 COLORREF是一个4字节类型,你有3字节像素。以COLORREF值数组的形式访问数据将不起作用。相反,您应该将其作为字节数组访问,每个像素位于((x + y * width)* 3)。各个频道的顺序由格式名称表示。因此,如果是24bppBGR,你需要数据[(x + y * width)* 3]来获得蓝色通道,数据[(x + y *宽度)* 3 + 1]用于绿色,数据[(x + y) *宽度)* 3 + 2]为红色。

如果你真的想要一个像素数组,你可以创建一个包含3个BYTE字段的结构,但由于这些字段的含义取决于像素格式,因此可能没用。

实际上,您不能假设任意图像将以24位格式加载。您可以获得的格式数量大于您可以合理预期支持的格式数量。

相反,您应该使用WICConvertBitmapSource将数据转换为可以使用的格式。如果您更喜欢使用COLORREF数组和相关宏,请使用GUID_WICPixelFormat32bppBGR。