chore(art): 主角像素样例三件留存——美术素材改走 ComfyUI 拍板批产物(第58条收口)

This commit is contained in:
DKChan committed 2026-09-16 20:55:11 +08:00
1 parent 131d1047e1
commit d76a023fa9
3 files changed
+128

No files matched your search

+128
View File
@@ -0,0 +1,128 @@
# -*- coding: utf-8 -*-
"""
主角站姿像素画样例生成器 — Dungeon Sweeper
依据 design/art/art-bible.md:
- 小人蓝 #2E6E8E 主色(§4.1) / 亮色描边+落影底盘轮廓通道(§3.1)
- 3 头身候选档(§3.1 两档之一;终稿归 §5 角色批)
- 窄/直立/对称/凹凸≤2,剑收于剪影内(§3.1/§3.4)
- 不用红(危险专属)/金(收益专属)/紫赤 300-345° 禁入带(§4.2)
输出: hero-standing-pose.png (1x) + hero-standing-pose-preview.png (8x 四联测试条)
"""
from PIL import Image, ImageOps
PAL = {
'O': (255, 246, 224, 255), # 亮色描边(暖白)
'b': (85, 144, 175, 255), # 蓝高光(小人蓝同族)
'B': (46, 110, 142, 255), # 小人蓝 §4.1
'd': (31, 74, 96, 255), # 蓝暗部(同族)
'S': (242, 199, 156, 255), # 肤色(暖)
's': (214, 159, 108, 255), # 肤暗部
'E': (51, 38, 27, 255), # 数字墨(眼) §4.1
'T': (138, 90, 52, 255), # 皮革(木色族 §4.4)
't': (92, 58, 30, 255), # 皮革暗部
'W': (183, 195, 203, 255), # 剑-钢
'w': (132, 147, 157, 255), # 剑-钢暗部
'G': (110, 91, 62, 255), # 落影底盘(暖深)
}
# 左半 16 列(col 0..15),右半水平镜像;-figure 对称剪影
LEFT = [
"................", # 0
"................", # 1
"................", # 2
".............OOO", # 3 兜帽顶
"............OBBB", # 4
"...........Obbbb", # 5
"...........ObbBB", # 6
"...........ObBBB", # 7
"...........OSSSS", # 8 额/脸顶(加宽脸窗)
"...........OSSES", # 9
"...........OSSES", # 10 眼(下移一档更亲和)
"...........OSSSS", # 11
"...........OSsss", # 12 下巴暗
"...........Odddd", # 13 兜帽收底
"..........Oddddd", # 14 肩起
"..........OdBBBB", # 15 肩
"..........OdBbbB", # 16 胸(中高光)
".........OBBBbbB", # 17 臂现
".........OdTBbbB", # 18 臂+背带
".........OdTBbbB", # 19
".........OdTBbbB", # 20
".........OdTBbbB", # 21
".........OdTBbbB", # 22
".........OdTBbbB", # 23
".........OdTttTW", # 24 腰带+扣(2px 居中)
".........OdTttTW", # 25
".........OdTTTTt", # 26 双手套握柄
".........OddBBBt", # 27 柄下
".........OBBOWWW", # 28 剑格
".........OBBBBBW", # 29 髋/剑身起
"..........OdBddW", # 30 腿+剑
"..........OdBddW", # 31
"..........OdBddW", # 32
"..........OdBddW", # 33
"..........OdBddW", # 34
"..........OdBddW", # 35
"..........OdBddW", # 36
"..........OTTttW", # 37 靴
"..........OTTttW", # 38
"..........OTTttW", # 39
"..........OTTttW", # 40
"..........OttttW", # 41 靴底
"..............OW", # 42 剑尖
"................", # 43
".........GGGGGGG", # 44 落影底盘
"...........GGGGG", # 45
"................", # 46
"................", # 47
]
W, H = 32, 48
grid = [['.'] * W for _ in range(H)]
for y, lft in enumerate(LEFT):
for x, ch in enumerate(lft):
grid[y][x] = ch
grid[y][W - 1 - x] = ch
# 剑身右侧 1px 暗部(col 16),避免完全对称的死平
for y in range(29, 42):
if grid[y][15] == 'W':
grid[y][16] = 'w'
def render(scale=1):
img = Image.new('RGBA', (W, H), (0, 0, 0, 0))
px = img.load()
for y in range(H):
for x in range(W):
c = PAL.get(grid[y][x])
if c:
px[x, y] = c
return img.resize((W * scale, H * scale), Image.NEAREST)
def on_bg(img, color):
bg = Image.new('RGBA', img.size, color + (255,))
bg.alpha_composite(img)
return bg
one_x = render(1)
one_x.save('hero-standing-pose.png')
# 测试条: 掩尘底 / 裸土底 / 暗底 / 灰度(轮廓通道验证)
x8 = render(8)
tiles = [
on_bg(x8, (201, 175, 131)), # 掩尘 #C9AF83
on_bg(x8, (179, 154, 120)), # 裸土 #B39A78
on_bg(x8, (46, 42, 38)), # 暗底对照
ImageOps.grayscale(on_bg(x8, (201, 175, 131))).convert('RGBA'),
]
GAP = 24
strip = Image.new('RGBA',
(len(tiles) * x8.width + (len(tiles) + 1) * GAP, x8.height + 2 * GAP),
(250, 244, 230, 255))
for i, t in enumerate(tiles):
strip.alpha_composite(t, (GAP + i * (x8.width + GAP), GAP))
strip.save('hero-standing-pose-preview.png')
print('done:', one_x.size, '->', strip.size)
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 B