C++ GDI无法转换为具有精确调色板的索引颜色? 总结
使用Windows GDI将24位颜色转换为索引颜色,GDI似乎选择了“足够接近”的颜色,即使所提供的调色板中存在完全匹配的颜色 有人能确认这是GDI问题吗?或者我在什么地方犯了错误 也许有一个“请检查整个调色板的颜色匹配”的标志,我没有找到 注意:这与量化无关。源是24位的,但包含256种或更少的颜色,因此精确的调色板计算起来很简单。问题是GDI没有使用完整的调色板 变通办法 我自己通过映射颜色解决了这个问题,但我更喜欢使用GDI,因为它应该得到更好的优化。问题是,它似乎“快速但错误” 详细说明 我的源图像为24位,但使用256色(或更少)。我为它生成一个精确的调色板,并要求GDI使用该调色板将图像转换为索引位图。对于某些像素,GDI选择相似但不精确的颜色,即使调色板中其他地方有精确的颜色。这会破坏平滑的渐变 此问题发生在:C++ GDI无法转换为具有精确调色板的索引颜色? 总结,c++,winapi,gdi,C++,Winapi,Gdi,使用Windows GDI将24位颜色转换为索引颜色,GDI似乎选择了“足够接近”的颜色,即使所提供的调色板中存在完全匹配的颜色 有人能确认这是GDI问题吗?或者我在什么地方犯了错误 也许有一个“请检查整个调色板的颜色匹配”的标志,我没有找到 注意:这与量化无关。源是24位的,但包含256种或更少的颜色,因此精确的调色板计算起来很简单。问题是GDI没有使用完整的调色板 变通办法 我自己通过映射颜色解决了这个问题,但我更喜欢使用GDI,因为它应该得到更好的优化。问题是,它似乎“快速但错误” 详细说
- SetDIBitsToDevice
- 担架障碍物
- 比特比特
- 担架
- 循环中的SetPixel或SetPixelV(非常慢!)
- 使用我自己的代码进行映射
- Windows 7(NVidia硬件/驱动程序)
- Windows Vista(ATI硬件/驱动程序)
- Windows 2000(VMware硬件/驱动程序)
这篇文章包含了一些有关绘制调色板DIB的更多信息,这些信息可能是相关的(请参阅“调色板和DIB部分”一节)。我模糊地记得,在将调色板选择到DC中之后,您还需要调用
realizepalete(hdc)
。我们很久以前就抛弃了调色板代码,以至于代码不再出现在源代码树中。我从你的代码中看到,你已经尝试过了,但我建议你可能还想再玩一次
我记得调色板代码非常脆弱,我们尽快停止使用它
一些旧的AVI文件将有8位调色板视频,其中嵌入调色板,因此这些文件的播放代码需要加载调色板。我记得realize没有做任何事情,除非你是前台应用,但这应该只适用于屏幕DC,而不是内存DC
如果您搜索可以播放调色板AVI的示例源代码,您可能会找到一些显示使调色板工作的神奇公式的东西
对不起,我帮不上忙了 我遇到了完全相同的问题,最终联系了微软并向他们提供了一个测试用例。在测试用例中,我提供了一个24位DIB中有128种颜色的渐变图像,然后我将其转换为8位DIB,该DIB是使用包含24位图像中所有128种颜色的颜色表创建的。转换后,8位图像仅使用了128种颜色中的65种 总结他们的反应:
这不是一个bug,GDI在向下转换图像的颜色深度时使用了足够接近的计算。这在任何地方都没有记录,确保所有原始颜色准确转换的唯一方法是自己手动操作像素。在选择DIB后,我尝试在目标DC上设置DIBColorTable,但结果相同。还尝试将SelectPalette调用移动到DIB选择之后,并在两个位置的SelectPalette之后添加回RealizePalette调用,但没有成功。我已经更新了示例代码,以包含SetDIBColorTable调用FWIW。(先前版本的代码移到了GdiIndexColor_old.zip)谢谢您的回复!我会尝试任何想法。+1的答案似乎是正确的。这个问题已经问了将近一年了,但它可能在将来仍然会对某人有所帮助。谢谢里斯!令人失望的是发现事情就是这样,但很高兴知道我没有做错什么。