Files

58 lines
2.3 KiB
Python

#!/usr/bin/env python3
"""Turn generated effect sheets (a 2x4 grid of frames on black) into the effect atlas of the
high-res style: every frame cut out (a margin off, the cell frames the model drew), the dark
background turned into transparency (alpha from the brightness, the colour divided by it, so
glows and smoke keep their soft edges), scaled to 64x64; one row of 8 frames per sheet.
Usage:
make_fx.py out.png sheet1-raw.png sheet2-raw.png ... [--margin 0.08] [--floor 0.1]
--floor brightness counted as background (the model's not quite black)
Writes out.png (8 x 64 wide, 64 per sheet high) and out-preview.png (on grey, 2x). Needs Pillow.
"""
import argparse
from PIL import Image
def main():
ap = argparse.ArgumentParser()
ap.add_argument("out")
ap.add_argument("sheets", nargs="+")
ap.add_argument("--margin", type=float, default=0.08)
ap.add_argument("--floor", type=float, default=0.1)
a = ap.parse_args()
size = 64
atlas = Image.new("RGBA", (8 * size, len(a.sheets) * size), (0, 0, 0, 0))
for row, path in enumerate(a.sheets):
img = Image.open(path).convert("RGB")
w, h = img.size
for k in range(8):
r, c = divmod(k, 4)
x0, x1 = c * w / 4, (c + 1) * w / 4
y0, y1 = r * h / 2, (r + 1) * h / 2
m = a.margin * (x1 - x0)
cell = img.crop((int(x0 + m), int(y0 + m), int(x1 - m), int(y1 - m))).resize((size, size), Image.BOX)
px = cell.load()
out = Image.new("RGBA", (size, size))
op = out.load()
for y in range(size):
for x in range(size):
rr, gg, bb = (v / 255 for v in px[x, y])
al = max(0.0, (max(rr, gg, bb) - a.floor) / (1 - a.floor))
if al < 0.03:
op[x, y] = (0, 0, 0, 0)
continue
k2 = max(rr, gg, bb)
op[x, y] = (int(255 * rr / k2), int(255 * gg / k2), int(255 * bb / k2), int(255 * min(1.0, al * 1.3)))
atlas.paste(out, (k * size, row * size))
atlas.save(a.out)
prev = Image.new("RGBA", atlas.size, (70, 66, 74, 255))
prev.alpha_composite(atlas)
prev.resize((prev.width * 2, prev.height * 2), Image.NEAREST).save(a.out.replace(".png", "-preview.png"))
print(a.out)
if __name__ == "__main__":
main()