Toolkitly

像素画调色板转换器

读出一张图里的每一种颜色,压缩到指定的色数,或者把画面映射到 Game Boy、PICO-8、 Commodore 64 的调色板上。免费、无需注册,所有像素都留在你的浏览器里。

不会上传任何文件——图片在你的浏览器里解码和重新上色。

怎么把一张图转到指定调色板

四步,其中一个设置是多数工具做错的地方。

  1. 1载入你的图把 PNG、WebP、GIF 或 JPEG 拖到虚线框里,或点击选择文件,也可以直接从剪贴板粘贴。 文件名下面那个颜色数,是这张图实际含有的不同颜色的数量。
  2. 2决定调色板从哪来要么从图片自身提取——压缩到 4、8、16、32 或你自己输入的任意色数;要么直接选一套主机调色板。
  3. 3颜色匹配保持在「按看起来像」这个设置决定每个像素落到哪一格。切到「按 RGB 数值」对比一下, 在色数少的调色板上差别一眼可见。
  4. 4导出你要的东西重新上色后的 PNG,或者单独导出调色板:.gpl、.hex、JSON 或色卡图。

「最接近的颜色」并不是个显然的问题

把一个像素吸附到调色板上,就是在量它离哪一格最近,而这需要先定义什么叫最近。最显然的答案——把红绿蓝当成三条坐标轴、量直线距离——是多数工具的做法, 而它错得能看出来。

sRGB 的数值和亮度不成正比。像 #005500 这样的中等绿色,三个通道的数值都不大, 按数值算距离它就是「深色」,于是被送到最暗的那一档。可它看起来完全不深: 绿色承担了人眼感知亮度的大部分,这个绿离中灰比离深色更近。

「按看起来像」是在 OKLab 里量距离——那是一个专门构造成 「数值上等量的一步,看起来也是等量的一步」的颜色空间。在十六色的调色板上, 两种方法多数时候答案一致。在只有四档的 Game Boy 调色板上, 它们不断给出不同答案,而那就是画面读得出来和糊成一团的区别。

那些颜色是怎么挑出来的

把一张图压缩到十六色,其实是两个问题而不是一个:挑哪十六种,以及每个像素变成其中哪一种。 后者就是上面说的最近色搜索。前者叫中位切分

一开始所有颜色装在同一个盒子里。找出跨度最大的那个盒子, 沿它最宽的那条通道劈成两半,重复到盒子数量等于要的颜色数。 每个盒子最后取里面颜色的平均值,并按用到它们的像素数加权—— 所以占了半张画面的天空会把它那个盒子拉向天空, 而不是和前景的精灵折中出一个谁也不像的颜色。

这和本站 GIF 导出把动画压进 255 色用的是同一套算法, 所以两边对「这张图是由什么颜色构成的」这个问题的回答是一致的。

主机调色板的出处

PICO-8Commodore 64 是数字,不是观点: PICO-8 官方文档给出了它那十六种颜色,这里的 C64 用的是 Pepto 实测的 VIC-II 色值, 也是 demoscene 圈子最终认下的那一套。Game Boy 的四档 是被广泛引用的 DMG 屏幕颜色。

NES 是被刻意排除的。它根本没有数字调色板—— PPU 生成的是模拟信号,你看到的是电视机对它的解释。 每个模拟器自带一套 RGB 近似值,而且彼此之间肉眼就能看出不一样。 任何一套 64 个数值被冠以「NES 调色板」的名义放出来, 都是某个模拟器作者的判断披上了硬件的外衣。 如果你手上有一套信得过的调色板,这里的 .hex 和 .gpl 就是将来做导入功能时会支持的格式。

什么时候用得上

给整套素材统一配色

画了几个月的东西一定会跑偏。从参考图里提取调色板, 再把每一张精灵图映射上去,这套素材才真的是一套颜色。

满足硬件或比赛的色数限制

做幻想主机的作品,或者参加有色数限制的 game jam? 先把画面映射到目标调色板上,看看哪些东西还立得住,别等规则来卡你。

扒一套你喜欢的配色

丢一张截图进来,读出它的颜色,导出 .gpl 载进 Aseprite。 值得拿走的本来就是配色本身。

压缩 GIF 或贴图

颜色少了,索引色输出就小。在这里主动减色并直接看到结果, 比让导出器替你决定要好。

导出格式

图片:原始尺寸的无损 PNG,里面只含调色板里的颜色, alpha 通道原样保留。完全透明的像素会保留它背后原本的颜色,既不参与统计也不被重新映射。

调色板:.gpl 是 GIMP 的调色板格式,Aseprite、Krita、GrafX2 也能读。.hex 是每行一个色值,最朴素的形式,也是 Lospec 导入用的格式。.json 是带名字的列表,给你自己的工具链用。.png 是把色卡画成图片,当参考图用。

别让引擎把你选的颜色改回去

调色板熬过了导出,然后被导入器悄悄改掉。

Godot

在导入面板里把贴图的 Filter 设成 Nearest。 过滤会在渲染时混合相邻像素,等于重新引入调色板里没有的颜色。

Unity

Filter Mode 选 Point (no filter),Compression 选 None。 DXT 压缩的原理就是对色块做近似,而那恰恰是固定调色板想要避免的事。

Aseprite

Palette → Load Palette 载入,然后 Sprite → Color Mode → Indexed 把精灵锁到这套颜色上。 之后再画的任何东西都只能用调色板里的颜色。

常见问题

怎么把一张图的配色提取出来?

把图拖进来,工具会数出里面每一种不同的颜色,按各自占画面的比例从多到少排列。像素画通常是几十种,照片会是几千种。结果可以导出成 .gpl 给 Aseprite 或 GIMP 用,导出成 .hex 粘到 Lospec,也可以导出 JSON 或色卡 PNG。

怎么把图片转成 Game Boy 或 PICO-8 的配色?

在「调色板」里选对应的主机,每个像素都会被吸附到那套调色板里最接近的颜色上。得到的是一张可以直接下载的真实图片,不是滤镜预览——导出的 PNG 里只会有调色板里的颜色,一种多余的都没有。

「按看起来像」和「按 RGB 数值」有什么区别?

区别在于每个像素被判定为最接近哪一格。直接比 RGB 数值等于把蓝色上的一步和绿色上的一步当成一样大,而眼睛不是这么看的:中等亮度的绿数值很小,按数值比就会被判成深色,然后被送到错误的那一档去。「按看起来像」是在 OKLab 里量距离,那个空间里等量的数值差看起来也是等量的差。在只有四档颜色的调色板上,两种设置出来的画面肉眼可辨。

抖动要不要开?

像素画不要开。每个像素都是特意放在那里的,抖动会在作者只选了一种颜色的地方撒上两种颜色的棋盘格。照片和平滑渐变值得开,因为那种情况下的替代品是明显的色带。这里提供 4×4 和 8×8 的有序抖动,不做误差扩散——误差扩散会把对一个像素的判断摊到邻居身上,于是精灵图裁剪一下,抖动花纹就变了。

压缩到 16 色,是怎么选出这 16 种的?

用中位切分。先把图里所有颜色装进一个盒子;找出跨度最大的那个盒子,沿它最宽的通道劈成两半;重复到盒子数量等于你要的颜色数为止。每个盒子最后取里面颜色的平均值,并按像素数加权——所以占了半张画面的天空会把它那个盒子拉向自己,而不是被平均掉。

为什么没有 NES 调色板?

因为根本不存在「那一套 NES 调色板」。这台主机不是查表出颜色,而是直接生成模拟信号,你看到的是电视机对这个信号的解释。于是每个模拟器都自带一套 RGB 近似值,而且互相之间肉眼可辨地不一致。随便挑一套不加说明地放上来,等于把猜测当成事实。这里收的都是有明确出处的调色板。

图片会被上传到服务器吗?

不会。图片是用浏览器的 Canvas API 在本地解码、统计和重新上色的。没有任何数据离开你的电脑,页面加载完之后断网也照样能用。

相关教程

相关工具