我有大约1000个相同大小的PNG图像(图块)(32px x 32px)。它们看起来都不一样,但有些非常相似(它们使用相同的颜色)。我必须在PNG图像(块)中总结它们,每个图像大约有50个图块。块大小是动态的,但不应该太小。
我的目标是最小化生成的块的大小。
Wikipedia告诉我,PNG文件大小取决于每个像素的颜色深度。
我的想法是将图块分组,以便每个组的颜色数量最少。还需要存储颜色索引,因此将每个图块保存为块不是最佳解决方案。进行强力运行需要很长时间,所以我希望能有一个很好的分组算法草图。
我认为当颜色数量超过1,2,4,8,16,32时,文件大小会“跳转”,依此类推。所以那些可能是要注意的门槛。
我现在将草拟一个不能产生最佳解决方案的算法
定义
引入群组距离。一组图块A对图块B的距离是B中不同颜色的数量,但不在A组中。
颜色(G)是一组瓷砖G中不同颜色的总量。
算法
1)选择第一个图块并将其放入Group1。
2)如果Colors(Group1)+ d_T小于 - 等于某个阈值,则将所有剩余的块循环并将具有最小的组块距离d_T的块T放入Group1中。 16.重复此步骤,直到找不到这样的瓷砖。
3)选择下一个剩余的瓷砖并重复该过程。
如果组太多或太少,请调整阈值。
不幸的是,这不一定会产生最好的结果(在相同的阈值下可能会有更大的组)。
是否可以更改此算法以返回最佳解决方案,还是应该选择其他方法?
是否有任何影响PNG尺寸的因素,我没有考虑过?
答案 0 :(得分:1)
这可以分为两个问题:
选择要放在一起的图像(以获得最小的调色板)
选择他们所处的顺序(利用PNG过滤器)
使用直方图。您可以对颜色进行分色(截断最低有效位)以获得更小的直方图以及不同图像的直方图之间更大的重叠。
然后将它们分组,例如对最不相似的直方图进行成对分组或使用K均值聚类。
不相似性将通过将添加到组的总直方图中的新直方图条目的数量来度量(例如,如果组已经使用蓝色和粉红色,则蓝色图像成本为0,蓝色+红色成本为1,黄色+绿色成本为2 )。
您还可以使用给定颜色(sqrt(num_pixels)
适用于pngquant)以及距离组直方图中最近可用颜色的距离来衡量相异度的像素数。
不仅仅是原始颜色数量,还有这些颜色的选择程度。具有较低均方误差的调色板几乎总能提供更好的压缩(每位视觉信息量),因为颜色不会在图像的不太重要的区域上“花费”很少。
对于第一次近似,您可以按照平滑度对图像进行排序。滤波器对渐变很有用,通常在嘈杂的区域没有帮助。
然后,当它改进过滤heuristic时,你可以通过随机交换图像来强制蛮力,即:
专注于#1,因为过滤器不会像最佳调色板那样节省大量成本。