Files
rui40000-RUI-Nodes/pixelart/palettes.py
T
rui40000andClaude Opus 4.8 b517c5714b feat: 新增像素化节点(面向像素游戏资产,含 AI 伪像素图网格还原)
产出真实小分辨率、颜色数受控、边缘硬朗的 sprite,而非马赛克滤镜。
纯 numpy/PIL 自研实现,无额外依赖、无需模型权重。

三种模式:按目标宽度 / 按像素块大小 / 自动检测网格。第三种专治
AI 生成的伪像素图(看着像素风,实际网格歪斜、边缘抗锯齿、上千颜色)。

选型说明:Pixel Snapper(MIT)解决的是「伪像素图 → 完美像素图」,
而「普通图 → 像素画」是另一个问题,核心在降采样与调色板量化,
故两条路都做进同一节点。

网格检测处理了两类经典误判:
- 谐波(八度)错误:取得最高分后回查真约数(octave killer)
- 内容周期冒充像素周期:把最佳/最差相位的分差并入评分(anti-phase)
评分用单元内方差而非相邻差分——差分对模糊极敏感,实测会把 4 像素
网格判成 24~28;组内方差则天然压制过大的 s。

实测:干净放大图 k=2~16 共 27/27 全对零八度错误;非方形网格与相位
偏移全对;普通插画正确判为未检出;端到端把 32×32 放大 10 倍加模糊
噪点的图还原回 32×32,与真值 MAE 0.0049;整数倍放大为纯复制无插值。

调色板在 CIELAB 空间聚类(RGB 距离与人眼感受相差很远,会丢暗部层次),
降采样默认主导色(均值会造出新颜色并糊边),内置 PICO-8/Game Boy 等
可确认取值的复古调色板。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 18:23:43 +08:00

46 lines
1.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
内置复古调色板
==============
只收录能确认取值的经典调色板,宁缺毋滥 —— 调色板值错了,
产出的美术资产就和目标机器/风格对不上,属于很难事后发现的错误。
灰阶类由代码等距生成,不存在记错的问题。
"""
import numpy as np
def _hex(*codes):
return np.array([[int(c[i:i + 2], 16) for i in (0, 2, 4)] for c in codes],
dtype=np.float32)
# PICO-8 官方 16 色
PICO8 = _hex(
"000000", "1D2B53", "7E2553", "008751", "AB5236", "5F574F", "C2C3C7",
"FFF1E8", "FF004D", "FFA300", "FFEC27", "00E436", "29ADFF", "83769C",
"FF77A8", "FFCCAA",
)
# 初代 Game Boy(DMG)四级绿
GAMEBOY = _hex("0F380F", "306230", "8BAC0F", "9BBC0F")
# 1-bit 黑白
ONEBIT = _hex("000000", "FFFFFF")
def _gray(n):
v = np.linspace(0, 255, n, dtype=np.float32)
return np.stack([v, v, v], axis=1)
PALETTES = {
"PICO-8 (16色)": PICO8,
"Game Boy (4色绿)": GAMEBOY,
"黑白 1-bit (2色)": ONEBIT,
"灰阶 4 级": _gray(4),
"灰阶 8 级": _gray(8),
"灰阶 16 级": _gray(16),
}
PALETTE_NAMES = list(PALETTES.keys())