【问题标题】:Assign palettes to tiles of an image to fit within N palettes of K colors each将调色板分配给图像的图块以适合每个 K 种颜色的 N 个调色板
【发布时间】:2019-10-08 12:05:02
【问题描述】:

我正在编写一个用于处理平铺图像的工具。一个功能是将整个图像转换为瓦片集和瓦片图,例如一个 160x144 像素的图像将具有一组唯一的 8x8 瓦片和一个 20x18 瓦片 ID 地图。

下一个目标是支持调色板。在一些使用平铺图形的旧平台上,您可能有 8 个调色板,每个调色板 4 种颜色,或者每个 16 种颜色中的 16 种。我想使用尽可能少的调色板自动创建一组符合 N-by-K 限制的调色板;并将这些调色板分配给瓦片地图,如果不可能,则发出警报。

有一些明显的第一步:如果任何单个图块使用超过 K 种颜色,这是不可能的;一旦被选中,任何颜色是另一个子集的图块都可以轻松地共享其调色板。困难在于处理部分重叠的调色板。考虑 17 块瓷砖,每块有 15 种独特的颜色;如果有足够的重叠,它们可以适应 16x16 的调色板,但这可能是不可能的。

我希望动态编程解决方案可以在这里工作。在问题的任何阶段,都有部分瓷砖分配给调色板;并且决定将下一个图块分配给 N 个调色板中的哪一个。 (瓷砖甚至可能没有任何颜色与当时的最佳调色板选择相同;考虑 4 块瓷砖,每块有 4 种独特的颜色,它们都可以使用一个 16 色调色板。)

这个特殊问题已经解决了吗?有没有已知的算法,或者只是所有动态编程的一般技巧?

【问题讨论】:

    标签: graphics dynamic-programming combinatorics color-palette gameboy


    【解决方案1】:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-18
      • 2015-01-28
      • 1970-01-01
      • 2019-02-08
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      • 2019-10-20
      相关资源
      最近更新 更多