2020-06-26 07:16:16 +01:00
|
|
|
#!/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
|
|
|
|
|
2024-01-20 02:06:32 +00:00
|
|
|
import shutil
|
2020-06-26 07:16:16 +01:00
|
|
|
|
|
|
|
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')
|
2024-01-20 02:06:32 +00:00
|
|
|
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')
|
2020-06-26 07:16:16 +01:00
|
|
|
palette_path = joinp(mon_graphics, name, 'anim_front.png')
|
2024-01-20 02:06:32 +00:00
|
|
|
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)
|
2020-06-26 07:16:16 +01:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2024-01-19 17:52:34 +00:00
|
|
|
apply_front_palettes('graphics/object_events/pics/pokemon')
|