zyc 72e7df09cd Initial commit: AR avatar prototype
包含三个子项目:
- avatar-h5-renderer: Live2D Cubism 4 H5 渲染器 (Vite + TS)
- avatar_flutter_app: Flutter 容器 App (打包 H5 进 WebView)
- gif-export: puppeteer 导出 32 个动作的透明 GIF (供 ESP32 圆屏播放)

模型资源: Haru, Natori (含贴图、moc3、motions, expressions)
设计文档: AI驱动虚拟形象渲染方案_v5.1.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 11:14:10 +08:00

60 lines
2.0 KiB
Python

import os
import shutil
from PIL import Image
import colorsys
def shift_hue(img_path, hue_shift_amount):
# Backup original
orig_path = img_path.replace('.png', '_orig.png')
if not os.path.exists(orig_path):
shutil.copy2(img_path, orig_path)
# Open image
img = Image.open(orig_path)
if img.mode != 'RGBA':
img = img.convert('RGBA')
# Split into channels
r, g, b, a = img.split()
# Convert RGB to HSV, shift hue, convert back
out_r, out_g, out_b = [], [], []
r_data = r.getdata()
g_data = g.getdata()
b_data = b.getdata()
# We want a blue/cyan theme.
# Instead of relative shift, let's just map most hues to a blueish hue.
# Actually, a simple hue shift (e.g. + 0.4 in 0-1 range) might be safer to keep variation.
for rp, gp, bp in zip(r_data, g_data, b_data):
h, s, v = colorsys.rgb_to_hsv(rp/255.0, gp/255.0, bp/255.0)
# Shift hue towards blue (around 0.55 - 0.65 in HSV)
# Let's do a relative shift. If original is reddish (0-0.1), shifting by 0.5 makes it cyan/blue.
h = (h + hue_shift_amount) % 1.0
# Let's also desaturate slightly to make it more "ethereal" like the uploaded pic
s = min(s * 0.8, 1.0)
rn, gn, bn = colorsys.hsv_to_rgb(h, s, v)
out_r.append(int(rn * 255))
out_g.append(int(gn * 255))
out_b.append(int(bn * 255))
new_r = Image.new('L', img.size)
new_r.putdata(out_r)
new_g = Image.new('L', img.size)
new_g.putdata(out_g)
new_b = Image.new('L', img.size)
new_b.putdata(out_b)
new_img = Image.merge('RGBA', (new_r, new_g, new_b, a))
new_img.save(img_path)
print(f"Tinted and saved: {img_path}")
base_dir = "/Users/maidong/Desktop/AR测试/avatar-h5-renderer/public/Resources/Haru/Haru.2048/"
shift_hue(os.path.join(base_dir, "texture_00.png"), 0.5) # Shift to cyan/blue
shift_hue(os.path.join(base_dir, "texture_01.png"), 0.5)