GDI无法转换为具有精确调色板的索引颜色?

时间:2009-12-24 08:05:45

标签: c++ winapi gdi

摘要

使用Windows GDI将24位颜色转换为索引颜色,即使在提供的调色板中存在完全匹配,GDI也会选择“足够接近”的颜色。

任何人都可以确认这是一个GDI问题,还是我在某处犯了错误?

也许有一个“请检查整个调色板的颜色匹配”标志,我找不到了?

注意:这是关于量化的。源是24位但包含256或更少的颜色,因此精确的调色板很容易计算。问题是GDI没有使用完整的调色板。

解决方法

我通过自己映射颜色解决了这个问题,但我更喜欢使用GDI,因为它应该更好地进行优化。问题是,它似乎“快而错”。

详细说明

我的源图像是24位,但使用256(或更少)颜色。我为它生成一个精确的调色板,并要求GDI使用该调色板将图像传输到索引位图。对于某些像素,即使在调色板中的其他位置存在确切的颜色,GDI也会选择相似但不精确的颜色。这会破坏平滑的渐变。

此问题发生在:

  • 的SetDIBitsToDevice
  • 的StretchDIBits
  • 的BitBlt
  • StretchBlt

问题发生在:

  • 循环中的SetPixel或SetPixelV(非常慢!)
  • 使用我自己的代码进行映射

我已经测试了这个:

  • Windows 7(NVidia硬件/驱动程序)
  • Windows Vista(ATI硬件/驱动程序)
  • Windows 2000(VMware硬件/驱动程序)

在每次测试中,我都得到相同的结果。 (不仅是错误的颜色,而且总是相同的错误颜色。)

我认为这个问题不是色彩管理(ICM / ICC配置文件等),因为大多数API都说他们不使用它,我已经尝试过明确地将它关闭在GDI DC以及通过V5位图标头,我认为它不适用于我的vanlilla-Win2k VM。

测试项目

可以在此处找到简单的Win32 / GDI / VS2008测试项目的代码:

http://www.pretentiousname.com/data/GdiIndexColor.zip

Win32UI.cpp中的Test1函数是实际测试。它有两个RGBQUAD数组,一个是源图像,另一个是精确的调色板。它验证调色板确实是准确的,然后要求GDI使用上面提到的API转换图像,每次测试结果。对于每个测试,它会告诉你之前和之前的第一个不正确的像素。在颜色之后,或告诉你所有像素都是正确的,如果它工作。

谢谢!

感谢您阅读我的问题!对不起,如果这是我做一些非常愚蠢的事情的结果! : - )

3 个答案:

答案 0 :(得分:5)

我遇到了同样的问题,最终联系了Microsoft,并为他们提供了测试用例。在测试用例中,我提供了一个24位DIB中有128种颜色的渐变图像,然后我将其转换为8位DIB,该DIB是使用包含24位图像中所有128种颜色的颜色表创建的。转换后,8位图像仅使用了128种颜色中的65种。

总结他们的回应: 这不是一个错误,GDI在向下转换图像的颜色深度时确实使用了足够接近的计算。这在任何地方都没有真正记录,确保所有原始颜色完全转换的唯一方法是自己手动操作像素。

答案 1 :(得分:0)

您使用的是SetDIBColorTable()吗? This article似乎意味着,在绘制到DIB时,仅调用SelectPalette()是不够的,但是还需要调用SetDIBColorTable()来设置DIB的调色板:

  

但是,如果应用程序正在使用   在DIB部分,您创建一个逻辑   DIB颜色表中的调色板为   通常然后也通过DIB   颜色表到DIB部分用   调用SetDIBColorTable()。尽管   什么是“Platform SDK”文档   of RealizePalette()似乎意味着,   RealizePalette()不调整   DIB部分的颜色表。

本文包含有关绘制可能相关的调色板DIB的更多信息(请参阅“调色板和DIB部分”部分)。

答案 2 :(得分:0)

我依稀记得在将调色板选入DC后,您还需要调用RealizePalette(hdc)。很久以前我们抛弃了我们的调色板代码,代码甚至不再在我们的源代码树中了。我从你的代码中看到你alrady试过这个,但我建议你可能想要更多地玩这个。

我确实记得调色板代码非常脆弱,我们尽快停止使用它。

一些较旧的AVI文件将具有8位调色视频,其中嵌入了文件中的调色板,因此这些文件的播放代码需要加载实现调色板。我记得除非你是前台应用程序,才意识到没有做任何事情,但是它应该只适用于屏幕DC而不是内存DC。

如果您搜索可以播放调色板AVI的示例源代码,您可能会发现一些显示调色板工作的神奇公式的内容。

抱歉,我无法提供更多帮助。