feat: 对称方式可选 - 垂直翻转 / 180° 旋转
为 JQK 人物图和大小王素材添加 symmetry_mode 字段: - 'flip'(默认):下半身用垂直镜像(沿水平中线翻转,左右不变) - 'rotate':下半身用 180° 旋转(上下颠倒 + 左右镜像) 改动: - 后端 draw_face_card / draw_joker:根据 symmetry_mode 选不同的 PIL transpose - 前端 cardRenderer.js:face card 和 joker 都用统一的分支: - flip: translate + scale(1, -1) - rotate: translate + rotate(Math.PI) - DesignPanel.vue:JQK/大小王面板加下拉选择器,存到 card_overrides
This commit is contained in:
@@ -248,16 +248,24 @@ def draw_face_card(canvas, design, suit, rank, project, card_key, asset):
|
||||
new_w = int(body_h * img_ratio)
|
||||
img = img.resize((new_w, new_h), Image.LANCZOS)
|
||||
|
||||
# 取上半部分 + 上下翻转的下半部分(取上半 = 下半 = 整个图按上下中线翻转)
|
||||
# 取上半部分 + 下半部分
|
||||
top = img.crop((0, 0, img.width, img.height // 2))
|
||||
bot = img.crop((0, img.height // 2, img.width, img.height)).transpose(Image.FLIP_TOP_BOTTOM)
|
||||
bot_src = img.crop((0, img.height // 2, img.width, img.height))
|
||||
# symmetry_mode: 'flip' = 垂直翻转;'rotate' = 180° 旋转
|
||||
sym_mode = design.get('symmetry_mode', 'flip')
|
||||
if sym_mode == 'rotate':
|
||||
# 180° 旋转 = 先水平翻转再垂直翻转(PIL 没有一步到位的 180 旋转 transpose)
|
||||
bot_src = bot_src.transpose(Image.FLIP_LEFT_RIGHT)
|
||||
bot_src = bot_src.transpose(Image.FLIP_TOP_BOTTOM)
|
||||
else: # 'flip'(默认)
|
||||
bot_src = bot_src.transpose(Image.FLIP_TOP_BOTTOM)
|
||||
|
||||
# 拼接成 body_h 高的新图
|
||||
full = Image.new('RGBA', (img.width, body_h), (0, 0, 0, 0))
|
||||
top = top.resize((img.width, body_h // 2), Image.LANCZOS)
|
||||
bot = bot.resize((img.width, body_h - body_h // 2), Image.LANCZOS)
|
||||
bot_src = bot_src.resize((img.width, body_h - body_h // 2), Image.LANCZOS)
|
||||
full.paste(top, (0, 0), top)
|
||||
full.paste(bot, (0, body_h // 2), bot)
|
||||
full.paste(bot_src, (0, body_h // 2), bot_src)
|
||||
|
||||
full = full.resize((body_w, body_h), Image.LANCZOS)
|
||||
canvas.alpha_composite(full, (body_pad_x, body_pad_y_top))
|
||||
@@ -316,9 +324,14 @@ def draw_joker(canvas, design, which, project, card_key, asset):
|
||||
x = body_pad_x + offset_x + (body_w - img_copy.width) // 2
|
||||
y_top = body_pad_y_top + offset_y + (half_h - img_copy.height) // 2
|
||||
canvas.alpha_composite(img_copy, (x, y_top))
|
||||
img_flipped = img_copy.transpose(Image.FLIP_TOP_BOTTOM)
|
||||
y_bot = body_pad_y_top + half_h + offset_y + (half_h - img_flipped.height) // 2
|
||||
canvas.alpha_composite(img_flipped, (x, y_bot))
|
||||
# symmetry_mode: 'flip' = 垂直翻转;'rotate' = 180° 旋转
|
||||
sym_mode = design.get('symmetry_mode', 'flip')
|
||||
if sym_mode == 'rotate':
|
||||
img_bot = img_copy.transpose(Image.ROTATE_180)
|
||||
else:
|
||||
img_bot = img_copy.transpose(Image.FLIP_TOP_BOTTOM)
|
||||
y_bot = body_pad_y_top + half_h + offset_y + (half_h - img_bot.height) // 2
|
||||
canvas.alpha_composite(img_bot, (x, y_bot))
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user