我需要将24bppRGB转换为16bppRGB、8bppRGB、4bppRGB、8ppp灰度和4bpp灰度。有什么好的链接或其他建议吗?
最好使用Windows/GDI+
[编辑]速度比质量更重要。源图像是截图
[EDIT1]需要颜色转换以最小化空间
最佳答案
你最好像别人建议的那样给自己弄个图书馆。除了ImageMagick,还有其他的,比如OpenCV。把这个留给图书馆的好处是:
节省一些时间——减少算法的开发和测试时间
速度。大多数库的优化程度远远超过标准开发人员(比如我们自己)所能达到的水平
符合标准。有很多图像格式,使用库可以解决标准遵从性问题。
如果你是自己做的,那么你的问题可以分为以下几个子问题:
简单的color quantization。正如@Alf P.Steinbach指出的,这只是“缩小”颜色的数量。RGB24每个R、G、B通道有8位。对于RGB16,您可以执行a number of conversions:
R、G、B中每一个的位数相等。这通常意味着每一个4或5位。
偏爱绿色通道(人眼对绿色更敏感),给它6位。R和B得到5位。
您甚至可以对RGB24到RGB8执行相同的操作,但结果不会像托盘图像那样漂亮:
4位绿色,2位红色,2位蓝色。
3位绿色,5位红色和蓝色之间
托盘化(indexed color)。从RGB24到RGB8和RGB4。这是一个很难自己解决的问题。
颜色到灰度的转换。很简单。将RGB24转换为YUV'颜色空间,并保留Y'通道。这将给你8ppp灰度。如果你想要4bpp灰度,那么你要么量化,要么做托盘化。
同时请务必查看chroma subsampling。通常,您可以将比特率降低三分之一,而不会对图像质量造成可见的损失。
一旦崩溃,你就能分而治之。问题1和2你可以很快解决。这将使你看到质量,你可以得到简单地做粗糙的颜色量化。
你是否想解决问题2取决于上面的结果。你说速度更重要,所以如果颜色量化的质量只够好的话,就不用操心托盘化了。
最后,你从没提过为什么要这么做。如果这是为了减少存储空间,那么您应该查看image compression。即使是无损压缩也会比单独减少颜色深度提供更好的效果。
编辑
如果设置使用PNG作为最终格式,则选项为quite limited,因为RGB16和RGB8都不是PNG header中的有效组合。
所以这意味着:不管比特深度是多少,如果你希望RGB彩色图像低于24bpp(每个通道8比特),你必须切换到索引颜色。这意味着您将无法利用上面提到的颜色量化和色度抽取——PNG不支持这种方法。所以这意味着你必须解决问题2——托盘化。
但在你考虑之前,还有一些问题:
你的图像的尺寸是多少?
你想要什么样的理想文件大小?
直接使用RBG24+PNG压缩可以得到多接近理想的文件大小?
你的图片来源是什么?你提到过屏幕截图,但是由于你非常关心磁盘空间,我开始怀疑你可能在处理图像序列(视频)。如果是这样,那么就可以比PNG压缩做得更好。
哦,如果你真的想用PNG做一些事情,那么一定要看看this library。
关于c++ - 图像色彩转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4928276/