Last active
February 2, 2018 21:08
-
-
Save PJB3005/b707d9da4926e0f7bd746ffc8e79988c to your computer and use it in GitHub Desktop.
Shifts the hue of states in a BYOND DMI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import argparse | |
import colorsys | |
from pathlib import Path | |
from byond.DMI import DMI | |
from byond.DMI.State import State as DMIState | |
from PIL import Image | |
def main() -> None: | |
parser = argparse.ArgumentParser(description="Hue shifts one or more states in a DMI, copying them into a new state(s) with a postfix. Preserves animations.") | |
parser.add_argument("filename", type=Path, help="The DMI to open and modify.") | |
parser.add_argument("shiftamount", type=float, help="The amount to shift the hue, in degrees.") | |
parser.add_argument("prefix", help="The prefix to apply to each copied state.") | |
parser.add_argument("statenames", nargs="+", help="The names of the states to hue shift.") | |
args = parser.parse_args() | |
dmi = DMI(args.filename) | |
dmi.loadAll() | |
for statename in args.statenames: | |
if statename not in dmi.states: | |
print(f"State not in DMI: {statename}! Skipping.") | |
continue | |
shift_state(dmi, statename, args.shiftamount, args.prefix) | |
def shift_state(dmi: DMI, statename: str, amount: float, prefix: str) -> None: | |
state = dmi.states[statename] | |
newstate = clone_state(state, prefix + state.name) | |
for icon in newstate.icons: | |
shift_image(icon, amount) | |
dmi.states[newstate.name] = newstate | |
dmi.save(dmi.filename) | |
def shift_image(image: Image.Image, amount: float) -> None: | |
pixels = image.load() | |
for x in range(image.width): | |
for y in range(image.height): | |
r, g, b, a = pixels[x, y] | |
h, s, v = colorsys.rgb_to_hsv(r/255, g/255, b/255) | |
h = (h + amount/360.0) % 1.0 | |
r, g, b = colorsys.hsv_to_rgb(h, s, v) | |
pixels[x, y] = (int(r * 255), int(g * 255), int(b * 255), a) | |
def clone_state(state: DMIState, new_name: str) -> DMIState: | |
newstate = DMIState(new_name) | |
newstate.hotspot = state.hotspot | |
newstate.frames = state.frames | |
newstate.dirs = state.dirs | |
newstate.movement = state.movement | |
newstate.loop = state.loop | |
newstate.rewind = state.rewind | |
newstate.delay = state.delay[:] | |
newstate.positions = state.positions[:] | |
newstate.icons = [None] * len(state.icons) | |
for index, icon in enumerate(state.icons): | |
icon.save("wat.png") | |
newstate.icons[index] = icon.copy() | |
return newstate | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment