#!/usr/bin/env python3 """ Extract sprites from HGSS follower spritesheets. """ import os.path from os.path import join as joinp import subprocess import sys from glob import glob import png from tqdm import tqdm import shutil def stack_sprite(name, path): frames = [joinp(path, 'down', name), joinp(path, 'down', 'frame2', name), joinp(path, 'up', name), joinp(path, 'up', 'frame2', name), joinp(path, 'left', name), joinp(path, 'left', 'frame2', name)] output = joinp(path, name) subprocess.run(['convert'] + frames + ['+append', output], check=True) print(f'Stacked {output}') def closest_color(c, palette): min_d = float('inf') best = 0 r1, g1, b1 = c for i, (r2, g2, b2) in enumerate(palette[1:], 1): # Color diff from https://stackoverflow.com/questions/1847092/given-an-rgb-value-what-would-be-the-best-way-to-find-the-closest-match-in-the-d d = ((r2-r1)*0.30)**2 + ((g2-g1)*0.59)**2 + ((b2-b1)*0.11)**2 if d < min_d: min_d = d best = i return best def apply_palette(palette_file, input_file, output_file): # Apply one file's palette to another plt = png.Reader(palette_file) plt.read() target_palette = tuple(c[:3] for c in plt.palette()) inp = png.Reader(input_file) w, h, rows, info = inp.read() src_palette = tuple(c[:3] for c in inp.palette()) new_rows = [[closest_color(src_palette[c][:3], target_palette) if c else 0 for c in row] for row in rows] with open(output_file, 'wb') as f: w = png.Writer(width=w, height=h, bitdepth=4, palette=target_palette) w.write(f, new_rows) # Sprites from https://veekun.com/dex/downloads def apply_front_palettes(ow_dir, project_root=''): mon_graphics = joinp(project_root, 'graphics', 'pokemon') for x in os.walk(ow_dir): current_dir = x[0] sub_dir = current_dir[len(ow_dir) + 1:1000] t = tqdm(sorted(glob(joinp(current_dir, '*.png')))) spaces = 0 for path in t: name, _ = os.path.splitext(os.path.basename(path)) name = joinp(sub_dir, name) # old_path = joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', f'{name}.png') # new_path = joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', name, 'follower.png') # os.mkdir(joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', name)) # shutil.move(old_path, new_path) spaces = min(max(len(name), spaces), 10) t.set_description(name + ' '*(spaces-len(name))) output_path = joinp(project_root, 'graphics', 'object_events', 'pics', 'pokemon', f'{name}.png') palette_path = joinp(mon_graphics, name, 'anim_front.png') try: apply_palette(palette_path, path, output_path) except Exception as e: palette_path = joinp(mon_graphics, name, 'front.png') try: apply_palette(palette_path, path, output_path) except Exception as e2: t.write(f'{name}: {e2.__class__.__name__}: {e2}', file=sys.stderr) if __name__ == '__main__': apply_front_palettes('graphics/object_events/pics/pokemon')