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)