Dedicated large inspection art for graphics cards
192x128 drawings made for the magnifier tray instead of enlarging the 48x32 item sprite: nine-blade fans, fin stack, heat pipes, power connector, PCB parts, per-contact gold fingers; back with brushed backplate, QR and barcode sticker, seal. Appearance overlays share coordinates with the base. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c05fe41ca9
commit
dd95aad7aa
37 files changed
+450
-2
No files matched your search
+443
@@ -0,0 +1,443 @@
|
||||
#!/usr/bin/env python3
|
||||
"""显卡检视大图(192×128):放大镜检视台里用的细节图,不是小图的放大版。
|
||||
正面:七叶风扇、鳍片、热管、供电口、PCB 元件与逐根金手指;背面:拉丝背板、丝印凹槽、二维码与条码贴纸、封条。
|
||||
叠加图与底图同尺寸、坐标一致,只画变化的像素。"""
|
||||
import math
|
||||
import random
|
||||
from sprites import Canvas, C, key, MODELS
|
||||
|
||||
BW, BH = 192, 128
|
||||
FANS = ((68, 51), (142, 51))
|
||||
FR = 30 # 风扇半径
|
||||
SH0, SH1 = (24, 14), (186, 96) # 散热罩 左上 / 右下
|
||||
FING_Y0, FING_Y1 = 109, 122
|
||||
NOTCH_X = 112
|
||||
|
||||
# 5×7 像素字(丝印与品牌字)
|
||||
F57 = {
|
||||
'R': ['11110', '10001', '10001', '11110', '10100', '10010', '10001'],
|
||||
'Z': ['11111', '00001', '00010', '00100', '01000', '10000', '11111'],
|
||||
'X': ['10001', '10001', '01010', '00100', '01010', '10001', '10001'],
|
||||
'P': ['11110', '10001', '10001', '11110', '10000', '10000', '10000'],
|
||||
'M': ['10001', '11011', '10101', '10101', '10001', '10001', '10001'],
|
||||
'D': ['11110', '10001', '10001', '10001', '10001', '10001', '11110'],
|
||||
'T': ['11111', '00100', '00100', '00100', '00100', '00100', '00100'],
|
||||
'i': ['00100', '00000', '01100', '00100', '00100', '00100', '01110'],
|
||||
'O': ['01110', '10001', '10001', '10001', '10001', '10001', '01110'],
|
||||
'B': ['11110', '10001', '10001', '11110', '10001', '10001', '11110'],
|
||||
'I': ['01110', '00100', '00100', '00100', '00100', '00100', '01110'],
|
||||
'A': ['01110', '10001', '10001', '11111', '10001', '10001', '10001'],
|
||||
'0': ['01110', '10001', '10011', '10101', '11001', '10001', '01110'],
|
||||
'1': ['00100', '01100', '00100', '00100', '00100', '00100', '01110'],
|
||||
'2': ['01110', '10001', '00001', '00110', '01000', '10000', '11111'],
|
||||
'3': ['11110', '00001', '00001', '01110', '00001', '00001', '11110'],
|
||||
'4': ['00010', '00110', '01010', '10010', '11111', '00010', '00010'],
|
||||
'5': ['11111', '10000', '11110', '00001', '00001', '10001', '01110'],
|
||||
'6': ['00110', '01000', '10000', '11110', '10001', '10001', '01110'],
|
||||
'7': ['11111', '00001', '00010', '00100', '01000', '01000', '01000'],
|
||||
'8': ['01110', '10001', '10001', '01110', '10001', '10001', '01110'],
|
||||
'9': ['01110', '10001', '10001', '01111', '00001', '00010', '01100'],
|
||||
}
|
||||
|
||||
|
||||
def text57(c, x, y, s, color, scale=1, skew=False, gap=1):
|
||||
i = 0
|
||||
for ch in s:
|
||||
if ch == ' ':
|
||||
x += 3 * scale
|
||||
continue
|
||||
dy = (i % 2) * scale if skew else 0
|
||||
for r, row in enumerate(F57[ch]):
|
||||
for k, bit in enumerate(row):
|
||||
if bit == '1':
|
||||
c.rect(x + k * scale, y + r * scale + dy, x + k * scale + scale - 1, y + r * scale + scale - 1 + dy, color)
|
||||
x += (5 + gap) * scale + (scale if skew and i % 3 == 2 else 0)
|
||||
i += 1
|
||||
|
||||
|
||||
def outline(c, col='O'):
|
||||
solid = lambda v: v is not None
|
||||
get = lambda x, y: c.px[y][x] if 0 <= x < c.w and 0 <= y < c.h else None
|
||||
edge = [(x, y) for y in range(c.h) for x in range(c.w)
|
||||
if solid(get(x, y)) and any(not solid(get(x + dx, y + dy)) for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)))]
|
||||
for x, y in edge:
|
||||
c.put(x, y, col)
|
||||
|
||||
|
||||
def bracket(c):
|
||||
"""左端 I/O 挡板:折边、三个接口(HDMI 与两个 DP,内腔与触片)、散热网孔、底部螺丝。"""
|
||||
c.rect(2, 8, 22, 112, 'b')
|
||||
c.rect(2, 8, 4, 112, 'l'); c.rect(2, 8, 2, 112, 'h') # 受光折边
|
||||
c.rect(19, 8, 22, 112, 'd'); c.rect(21, 8, 22, 112, 'g') # 背光折边
|
||||
for x in range(5, 19): # 拉丝
|
||||
for y in range(9, 112, 2):
|
||||
c.put(x, y, 'b' if (x + y) % 5 else 'l')
|
||||
for i, y in enumerate((16, 36, 56)): # 三个接口
|
||||
c.rect(6, y, 17, y + 13, 'k')
|
||||
c.rect(6, y, 17, y, 'g'); c.rect(6, y, 6, y + 13, 'g')
|
||||
c.rect(7, y + 1, 16, y + 12, 'n')
|
||||
if i == 0: # HDMI:两侧斜角
|
||||
for k in range(3):
|
||||
c.put(7 + k, y + 12 - k, 'k'); c.put(16 - k, y + 12 - k, 'k')
|
||||
c.rect(9, y + 4, 14, y + 6, 'z')
|
||||
else: # DP:一边切角
|
||||
c.put(16, y + 12, 'k'); c.put(15, y + 12, 'k'); c.put(16, y + 11, 'k')
|
||||
c.rect(9, y + 4, 14, y + 5, 'z')
|
||||
for x in range(8, 16, 2):
|
||||
c.put(x, y + 9, 'Y')
|
||||
for y in range(78, 104, 4): # 散热网孔
|
||||
for x in range(7, 17, 3):
|
||||
c.rect(x, y, x + 1, y + 2, 'k')
|
||||
c.put(x, y, 'x')
|
||||
c.rect(9, 106, 14, 110, 'm'); c.rect(10, 107, 13, 109, 'g') # 底部螺丝
|
||||
c.put(11, 108, 'k'); c.put(12, 108, 'k'); c.put(11, 107, 'b')
|
||||
c.rect(9, 10, 14, 12, 'k')
|
||||
|
||||
|
||||
def fan(c, cx, cy, accent, accent_dark):
|
||||
"""风扇:九片弯曲扇叶(前缘高光、叶面渐变、叶尖暗边),外圈带四个固定螺丝,轴心带品牌圆标。"""
|
||||
R = FR
|
||||
for y in range(cy - R - 1, cy + R + 2):
|
||||
for x in range(cx - R - 1, cx + R + 2):
|
||||
dx, dy = x - cx, y - cy
|
||||
r = math.hypot(dx, dy)
|
||||
if r > R + 0.5:
|
||||
continue
|
||||
ang = (math.atan2(dy, dx) / (2 * math.pi)) % 1.0
|
||||
light = -(dx + dy) / (1.4 * R) # 左上为正
|
||||
if r >= R - 3.2: # 外圈
|
||||
c.put(x, y, 'h' if light > 0.5 else 'l' if light > 0.1 else 'b' if light > -0.4 else 'm')
|
||||
elif r >= R - 5.5: # 风道阴影
|
||||
c.put(x, y, 'n' if light < 0.2 else 'k')
|
||||
elif r <= 6.5: # 轴心
|
||||
if r <= 4.3:
|
||||
c.put(x, y, accent if light < 0.3 else accent_dark if r > 3 else 'w')
|
||||
else:
|
||||
c.put(x, y, 'h' if light > 0.2 else 'm' if light > -0.3 else 'd')
|
||||
else:
|
||||
t = (ang * 9 + (r - 7) * 0.060) % 1.0
|
||||
if t < 0.62:
|
||||
if t < 0.06:
|
||||
col = 'h'
|
||||
elif t < 0.40:
|
||||
col = 'l' if light > 0.25 else 'b' if light > -0.2 else 'm'
|
||||
else:
|
||||
col = 'b' if light > 0.2 else 'm' if light > -0.3 else 'g'
|
||||
if r > R - 8:
|
||||
col = 'g' if col in ('m', 'g') else 'm'
|
||||
c.put(x, y, col)
|
||||
else:
|
||||
c.put(x, y, 'n' if t < 0.9 else 'k')
|
||||
for k in range(4): # 外圈固定螺丝
|
||||
a = math.pi / 4 + k * math.pi / 2
|
||||
sx, sy = int(cx + math.cos(a) * (R - 1.5)), int(cy + math.sin(a) * (R - 1.5))
|
||||
c.rect(sx - 1, sy - 1, sx + 1, sy + 1, 'k')
|
||||
c.put(sx, sy, 'g')
|
||||
|
||||
|
||||
def gpu_front(accent, accent_dark, brand_text, burnt=False):
|
||||
c = Canvas(BW, BH)
|
||||
bracket(c)
|
||||
x0, y0 = SH0
|
||||
x1, y1 = SH1
|
||||
# 散热罩:石墨底,顶部受光亮边,左缘高光,右下阴影;右上角切斜
|
||||
for y in range(y0, y1 + 1):
|
||||
for x in range(x0, x1 + 1):
|
||||
if x > x1 - 8 and y < y0 + (x - (x1 - 8)): # 右上切角
|
||||
continue
|
||||
base = 'z'
|
||||
if y < y0 + 3: base = 'h' if x < x1 - 40 else 'l'
|
||||
elif y < y0 + 6: base = 'l' if x < x1 - 40 else 'b'
|
||||
elif y < y0 + 9: base = 'x'
|
||||
elif y > y1 - 4: base = 'n'
|
||||
c.put(x, y, base)
|
||||
for y in range(y0 + 3, y1): # 左缘
|
||||
c.put(x0, y, 'l'); c.put(x0 + 1, y, 'b'); c.put(x0 + 2, y, 'x')
|
||||
# 右端鳍片
|
||||
for x in range(x1 - 18, x1 + 1):
|
||||
for y in range(y0 + 10, y1 - 4):
|
||||
if x > x1 - 8 and y < y0 + (x - (x1 - 8)) + 2:
|
||||
continue
|
||||
c.put(x, y, 'x' if (x - (x1 - 18)) % 3 == 0 else 'g' if (x - (x1 - 18)) % 3 == 1 else 'n')
|
||||
c.rect(x1 - 20, y0 + 10, x1 - 19, y1 - 4, 'x')
|
||||
# 风扇之间的中筋
|
||||
c.rect(105, y0 + 8, 106, y1 - 5, 'k'); c.rect(107, y0 + 8, 107, y1 - 5, 'x')
|
||||
for cx, cy in FANS:
|
||||
fan(c, cx, cy, accent, accent_dark)
|
||||
# 前沿斜切装饰条:品牌色 + 品牌字
|
||||
for x in range(x0 + 4, x1 - 20):
|
||||
c.rect(x, y1 - 5, x, y1 - 3, accent if x % 11 else accent_dark)
|
||||
for k in range(18):
|
||||
c.rect(x0 + 4 + k, y1 - 5 - k // 2, x0 + 4 + k, y1 - 3 - k // 2 + 1, accent)
|
||||
text57(c, 112, 84, brand_text, 'h')
|
||||
# 顶沿:四根铜热管端头与 8 针供电口
|
||||
for i in range(4):
|
||||
x = 38 + i * 9
|
||||
c.rect(x, 7, x + 6, y0 - 1, 'p'); c.rect(x, 7, x + 1, y0 - 1, 'h' if i == 0 else 'p')
|
||||
c.rect(x + 5, 7, x + 6, y0 - 1, 'q'); c.rect(x, 7, x + 6, 7, 'q')
|
||||
c.rect(112, 5, 154, y0 - 1, 'n'); c.rect(112, 5, 154, 6, 'z')
|
||||
for i in range(8):
|
||||
c.rect(114 + i * 5, 7, 116 + i * 5, 9, 'k'); c.put(115 + i * 5, 8, 'Y')
|
||||
# PCB:阻焊绿、边缘高光、元件与走线
|
||||
for y in range(y1 + 1, FING_Y0):
|
||||
for x in range(x0, x1 + 1):
|
||||
c.put(x, y, 'G' if y < y1 + 4 else 'g2')
|
||||
for x in range(x0, x1 + 1):
|
||||
c.put(x, y1 + 1, 'T') if False else None
|
||||
random.seed(7)
|
||||
for i in range(14):
|
||||
sx = x0 + 6 + i * 11
|
||||
c.rect(sx, y1 + 3, sx + 3, y1 + 5, 'k' if i % 3 else 'b')
|
||||
c.rect(sx, y1 + 3, sx + 3, y1 + 3, 'x')
|
||||
for k in range(4):
|
||||
c.put(sx + k, y1 + 7, 'Y' if k % 2 == 0 else 'g2')
|
||||
# 金手指:逐根(3 像素宽,1 像素缝),PCIe 键位缺口
|
||||
for x in range(x0 + 2, x1 - 2):
|
||||
if NOTCH_X - 2 <= x <= NOTCH_X + 3 or (x - x0) % 4 == 3:
|
||||
continue
|
||||
for y in range(FING_Y0, FING_Y1 + 1):
|
||||
c.put(x, y, 'h' if y == FING_Y0 else 'Y' if (x - x0) % 4 != 0 else 'p')
|
||||
c.put(x, FING_Y1, 'e')
|
||||
c.rect(x0, FING_Y0, x1, FING_Y0, 'g2')
|
||||
for y in range(FING_Y0 + 1, FING_Y1 + 1): # 缝里露出 PCB
|
||||
for x in range(x0 + 2, x1 - 2):
|
||||
if c.px[y][x] is None and not (NOTCH_X - 2 <= x <= NOTCH_X + 3):
|
||||
c.put(x, y, 'g2')
|
||||
if burnt:
|
||||
for cx, cy in FANS:
|
||||
for dx, dy in ((0, 0), (5, -5), (-6, 6), (8, 4), (-9, -3), (2, 10)):
|
||||
c.rect(cx + dx - 2, cy + dy - 2, cx + dx + 2, cy + dy + 2, 'c')
|
||||
for x in range(x0 + 4, x1 - 20):
|
||||
c.rect(x, y1 - 5, x, y1 - 3, 'e')
|
||||
for dx, dy in ((30, 70), (90, 40), (150, 80), (60, 30), (120, 88)):
|
||||
c.rect(dx, dy, dx + 4, dy + 3, 'c')
|
||||
outline(c)
|
||||
return c
|
||||
|
||||
|
||||
def screw(c, x, y):
|
||||
c.rect(x - 3, y - 3, x + 3, y + 3, 'm')
|
||||
c.rect(x - 3, y - 3, x - 1, y - 3, 'h')
|
||||
c.rect(x - 2, y - 2, x + 2, y + 2, 'b')
|
||||
c.rect(x - 2, y, x + 2, y, 'k'); c.rect(x, y - 2, x, y + 2, 'k')
|
||||
c.rect(x + 2, y + 2, x + 3, y + 3, 'd')
|
||||
|
||||
|
||||
def qr(c, x, y, seed):
|
||||
rnd = random.Random(seed)
|
||||
n = 21
|
||||
c.rect(x - 1, y - 1, x + n, y + n, 'w')
|
||||
for j in range(n):
|
||||
for i in range(n):
|
||||
on = rnd.random() < 0.5
|
||||
for fx, fy in ((0, 0), (n - 7, 0), (0, n - 7)):
|
||||
if fx <= i < fx + 7 and fy <= j < fy + 7:
|
||||
li, lj = i - fx, j - fy
|
||||
on = li in (0, 6) or lj in (0, 6) or (2 <= li <= 4 and 2 <= lj <= 4)
|
||||
elif fx - 1 <= i <= fx + 7 and fy - 1 <= j <= fy + 7:
|
||||
on = False
|
||||
if on:
|
||||
c.put(x + i, y + j, 'n')
|
||||
|
||||
|
||||
def sticker(c, seed):
|
||||
"""序列号贴纸(右下):二维码、条码、两行小字。"""
|
||||
c.rect(86, 64, 172, 100, 'w')
|
||||
c.rect(86, 64, 172, 65, 'h'); c.rect(86, 99, 172, 100, 'l')
|
||||
c.rect(86, 64, 87, 100, 'h'); c.rect(171, 64, 172, 100, 'l')
|
||||
qr(c, 91, 70, seed)
|
||||
for x in range(118, 166):
|
||||
w = 1 + ((x * 7 + seed) % 3)
|
||||
if (x * 5 + seed) % 4 != 0:
|
||||
c.rect(x, 70, x, 84, 'n')
|
||||
text57(c, 118, 88, "0X5A70", 'n')
|
||||
c.rect(150, 88, 166, 94, 'm')
|
||||
|
||||
|
||||
def seal(c):
|
||||
"""封条(红底白字):压住贴纸右边缘。"""
|
||||
c.rect(174, 60, 182, 104, 'R')
|
||||
c.rect(174, 60, 175, 104, 'r2'); c.rect(181, 60, 182, 104, 'r2')
|
||||
for y in range(66, 100, 8):
|
||||
c.rect(176, y, 180, y + 3, 'w')
|
||||
c.put(178, y + 1, 'R')
|
||||
|
||||
|
||||
def gpu_back(accent, accent_dark, burnt=False):
|
||||
c = Canvas(BW, BH)
|
||||
bracket(c)
|
||||
x0, y0 = SH0
|
||||
x1, y1 = SH1
|
||||
for y in range(y0, y1 + 12):
|
||||
for x in range(x0, x1 + 1):
|
||||
c.put(x, y, 'd' if y % 2 else 'm' if (x // 3) % 4 else 'd')
|
||||
for y in range(y0, y1 + 12):
|
||||
c.put(x0, y, 'l'); c.put(x0 + 1, y, 'b'); c.put(x1, y, 'k'); c.put(x1 - 1, y, 'z')
|
||||
for x in range(x0, x1 + 1):
|
||||
c.put(x, y0, 'h'); c.put(x, y0 + 1, 'l'); c.put(x, y0 + 2, 'b')
|
||||
# 丝印凹槽(型号叠加图写在这里)
|
||||
c.rect(36, 24, 178, 52, 'z')
|
||||
c.rect(36, 24, 178, 25, 'k'); c.rect(36, 24, 37, 52, 'k')
|
||||
c.rect(36, 52, 178, 52, 'x'); c.rect(178, 24, 178, 52, 'x')
|
||||
# 品牌色斜条
|
||||
for x in range(x0 + 4, x1 - 4):
|
||||
c.rect(x, 56, x, 59, accent)
|
||||
c.put(x, 60, accent_dark)
|
||||
for k in range(20):
|
||||
c.rect(x1 - 6 - k, 55 - k // 2, x1 - 6 - k, 55 - k // 2 + 1, accent_dark)
|
||||
# 通风槽(左下)
|
||||
for y in range(70, 100, 6):
|
||||
c.rect(x0 + 10, y, x0 + 50, y + 3, 'k')
|
||||
c.rect(x0 + 10, y + 4, x0 + 50, y + 4, 'x')
|
||||
# 四角螺丝
|
||||
for sx, sy in ((x0 + 12, y0 + 10), (x1 - 12, y0 + 10), (x0 + 12, y1 - 2), (x1 - 12, y1 - 2)):
|
||||
screw(c, sx, sy)
|
||||
sticker(c, 5)
|
||||
seal(c)
|
||||
# 背面金手指(暗一档)
|
||||
for x in range(x0 + 2, x1 - 2):
|
||||
if NOTCH_X - 2 <= x <= NOTCH_X + 3 or (x - x0) % 4 == 3:
|
||||
continue
|
||||
for y in range(y1 + 14, FING_Y1 + 1):
|
||||
c.put(x, y, 'Y' if (x - x0) % 4 else 'p')
|
||||
for y in range(y1 + 12, y1 + 14):
|
||||
for x in range(x0, x1 + 1):
|
||||
c.put(x, y, 'g2')
|
||||
if burnt:
|
||||
for dx, dy in ((60, 30), (130, 40), (50, 80), (100, 70), (150, 90)):
|
||||
c.rect(dx, dy, dx + 6, dy + 4, 'c')
|
||||
outline(c)
|
||||
return c
|
||||
|
||||
|
||||
def new():
|
||||
return Canvas(BW, BH)
|
||||
|
||||
|
||||
# ---------- 叠加图 ----------
|
||||
|
||||
def ov_fan(kind):
|
||||
c = new()
|
||||
rnd = random.Random(11 + kind)
|
||||
for cx, cy in FANS:
|
||||
if kind == 1: # 积灰:叶片上一层灰点和灰絮
|
||||
for _ in range(190):
|
||||
a = rnd.random() * math.tau
|
||||
r = 8 + rnd.random() * (FR - 12)
|
||||
x, y = int(cx + math.cos(a) * r), int(cy + math.sin(a) * r)
|
||||
c.put(x, y, 'l' if rnd.random() < 0.6 else 'h')
|
||||
if rnd.random() < 0.3:
|
||||
c.put(x + 1, y, 'l')
|
||||
for _ in range(10): # 絮状长条
|
||||
a = rnd.random() * math.tau
|
||||
r = 10 + rnd.random() * (FR - 16)
|
||||
x, y = int(cx + math.cos(a) * r), int(cy + math.sin(a) * r)
|
||||
for k in range(5):
|
||||
c.put(x + k, y + (k // 2), 'w' if k % 2 == 0 else 'l')
|
||||
else: # 缺角:一片叶尖缺一块,露出风道黑底
|
||||
a0 = 0.9 if cx < 100 else 3.2
|
||||
for r in range(10, FR - 3):
|
||||
for da in (-0.20, -0.17, -0.13, -0.10, -0.06, -0.02, 0.02, 0.06, 0.10, 0.14):
|
||||
if r > FR - 14 + (da * 30) and r > 17:
|
||||
c.put(int(cx + math.cos(a0 + da) * r), int(cy + math.sin(a0 + da) * r), 'n')
|
||||
for r in range(17, FR - 3):
|
||||
c.put(int(cx + math.cos(a0 - 0.22) * r), int(cy + math.sin(a0 - 0.22) * r), 'h')
|
||||
return c
|
||||
|
||||
|
||||
def ov_fingers(kind):
|
||||
c = new()
|
||||
rnd = random.Random(21 + kind)
|
||||
x0, x1 = SH0[0], SH1[0]
|
||||
for x in range(x0 + 2, x1 - 2):
|
||||
if NOTCH_X - 2 <= x <= NOTCH_X + 3 or (x - x0) % 4 == 3:
|
||||
continue
|
||||
for y in range(FING_Y0 + 1, FING_Y1 + 1):
|
||||
if kind == 1: # 发暗:触点变褐
|
||||
c.put(x, y, 'e' if (x + y) % 3 else 'q')
|
||||
else: # 氧化:发绿的斑块
|
||||
if rnd.random() < 0.65:
|
||||
c.put(x, y, 'g2' if rnd.random() < 0.5 else 'G')
|
||||
return c
|
||||
|
||||
|
||||
def ov_bracket(kind):
|
||||
c = new()
|
||||
rnd = random.Random(31)
|
||||
if kind == 1: # 划痕
|
||||
for _ in range(9):
|
||||
x, y = rnd.randint(5, 17), rnd.randint(14, 100)
|
||||
for k in range(rnd.randint(5, 12)):
|
||||
c.put(x + k // 2, y + k, 'h' if k % 2 else 'k')
|
||||
else: # 接口数不对:第三个接口被板子封死
|
||||
c.rect(6, 56, 17, 69, 'b')
|
||||
c.rect(6, 56, 17, 56, 'h'); c.rect(6, 56, 6, 69, 'l'); c.rect(17, 56, 17, 69, 'd')
|
||||
for x in range(7, 17, 2):
|
||||
c.put(x, 62, 'm')
|
||||
return c
|
||||
|
||||
|
||||
def ov_text(model, skew):
|
||||
c = new()
|
||||
text57(c, 46, 31, model, 'l' if skew else 'h', scale=2, skew=skew, gap=1)
|
||||
return c
|
||||
|
||||
|
||||
def ov_sticker(kind):
|
||||
c = new()
|
||||
if kind == 1: # 手写序列号
|
||||
c.rect(86, 64, 172, 100, 'w')
|
||||
c.rect(86, 64, 172, 65, 'h'); c.rect(86, 99, 172, 100, 'l')
|
||||
c.rect(86, 64, 87, 100, 'h'); c.rect(171, 64, 172, 100, 'l')
|
||||
rnd = random.Random(41)
|
||||
for row in (74, 84, 92):
|
||||
x = 92
|
||||
while x < 164:
|
||||
w = rnd.randint(3, 7)
|
||||
for k in range(w):
|
||||
c.put(x + k, row + int(math.sin(k + x) * 1.5), 'O')
|
||||
c.put(x + k, row + 1 + int(math.sin(k + x) * 1.5), 'O')
|
||||
x += w + rnd.randint(2, 4)
|
||||
else: # 封条缺失:残留的胶痕与撕口
|
||||
c.rect(174, 60, 182, 104, 'd')
|
||||
for y in range(60, 105, 3):
|
||||
c.rect(174, y, 178 + (y % 5), y + 1, 'm')
|
||||
for y in range(62, 104, 6):
|
||||
c.rect(179, y, 181, y + 1, 'x')
|
||||
return c
|
||||
|
||||
|
||||
BIG = {}
|
||||
for _b, (_a, _ad, _t) in {'probidia': ('G', 'g2', 'PROBIDIA'), 'pmd': ('R', 'r2', 'PMD')}.items():
|
||||
BIG['gpu_big_%s_f' % _b] = (lambda a=_a, ad=_ad, t=_t: gpu_front(a, ad, t))
|
||||
BIG['gpu_big_%s_b' % _b] = (lambda a=_a, ad=_ad: gpu_back(a, ad))
|
||||
BIG['gpu_big_burnt_f'] = lambda: gpu_front('e', 'c', 'PROBIDIA', burnt=True)
|
||||
BIG['gpu_big_burnt_b'] = lambda: gpu_back('e', 'c', burnt=True)
|
||||
BIG_OV = {
|
||||
'gpu_big_ov_fan1': lambda: ov_fan(1), 'gpu_big_ov_fan2': lambda: ov_fan(2),
|
||||
'gpu_big_ov_fin1': lambda: ov_fingers(1), 'gpu_big_ov_fin2': lambda: ov_fingers(2),
|
||||
'gpu_big_ov_brk1': lambda: ov_bracket(1), 'gpu_big_ov_brk2': lambda: ov_bracket(2),
|
||||
'gpu_big_ov_stk1': lambda: ov_sticker(1), 'gpu_big_ov_stk2': lambda: ov_sticker(2),
|
||||
}
|
||||
for _m in MODELS:
|
||||
BIG_OV['gpu_big_ov_txt_' + key(_m)] = (lambda m=_m: ov_text(m, False))
|
||||
BIG_OV['gpu_big_ov_txs_' + key(_m)] = (lambda m=_m: ov_text(m, True))
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys, os
|
||||
if len(sys.argv) == 3 and sys.argv[1] == '--preview':
|
||||
d = sys.argv[2]
|
||||
def stack(base, *ovs):
|
||||
b = BIG[base]()
|
||||
for o in ovs:
|
||||
oc = BIG_OV[o]()
|
||||
for y in range(oc.h):
|
||||
for x in range(oc.w):
|
||||
if oc.px[y][x] is not None:
|
||||
b.px[y][x] = oc.px[y][x]
|
||||
return b
|
||||
bg = (0x6A, 0x72, 0x70)
|
||||
stack('gpu_big_probidia_f').png(os.path.join(d, 'big_f.png'), scale=5, bg=bg)
|
||||
stack('gpu_big_pmd_f', 'gpu_big_ov_fan1', 'gpu_big_ov_fin2', 'gpu_big_ov_brk2').png(os.path.join(d, 'big_f_fake.png'), scale=5, bg=bg)
|
||||
stack('gpu_big_pmd_b', 'gpu_big_ov_txs_rz6800', 'gpu_big_ov_stk1').png(os.path.join(d, 'big_b_fake.png'), scale=5, bg=bg)
|
||||
stack('gpu_big_probidia_b', 'gpu_big_ov_txt_rzx80ti').png(os.path.join(d, 'big_b.png'), scale=5, bg=bg)
|
||||
Reference in new issue
Block a user