SuperFamiconv能够为一些系统执行此操作,包括 SNES(16 个调色板,8 种颜色/调色板)和 GBC(8 个调色板,4 种颜色/调色板)。它也是开源的,所以他们的算法是可用的。
事实证明,对于给定真实大小的图像,动态编程对于“足够好”的解决方案并不是必需的。(不确定它对大型的效果如何,但这对我的目的来说并不重要。)
这是他们的算法到 Python 的翻译:
def optimize_palettes(tilepals, N, K):
"""
Return an optimized palette set for the given tile set.
tilepals -- A list of sets of unique colors used for each tile of the image
N -- The maximum number of palettes for one image
K -- The maximum number of colors for one tile palette
"""
# Check that each tilepal fits within the color limit
if any(len(s) > K for s in tilepals):
raise OverflowError, "A tile has more than %d unique colors" % K
# Remove duplicate tilepals
sets = []
for s in tilepals:
if s not in sets:
sets.append(s)
# Remove tilepals that are proper subsets of other tilepals
sets = [s for s in sets if not any(c != s and s.issubset(c) for c in sets)]
# Sort tilepals from most to fewest colors
sets.sort(key=len, reverse=True)
# Combine tilepals as long as they fit within the color limit
opt = []
for s in sets:
for cs in opt:
if len(s | cs) <= K:
cs.update(s)
break
else:
opt.append(s)
# Sort tilepals from most to fewest colors
opt.sort(key=len, reverse=True)
# Check that the palettes fit within the palette limit
if len(opt) > N:
raise OverflowError, "There are more than %d palettes" % N
return opt