54 lines
2.1 KiB
Python
54 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Turn a generated material picture into a texture for the furniture (props.rs): cropped,
|
|
optionally turned into grey detail (the furniture's colours tint it in the game), brightened to
|
|
a common mean and scaled to the high-res size and the pixel-art size.
|
|
|
|
Usage:
|
|
make_material.py raw.png out_prefix [--crop x0,y0,x1,y1] [--trim] [--color] [--mean 0.8]
|
|
|
|
--crop fractions of the picture to keep
|
|
--trim crop to the picture's object (everything that is not near-white background)
|
|
--color keep the colours (else grey detail)
|
|
--mean mean brightness of the result (0..1)
|
|
|
|
Writes out_prefix-64.png and out_prefix-16.png. Needs Pillow.
|
|
"""
|
|
import argparse
|
|
|
|
from PIL import Image, ImageOps, ImageStat
|
|
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("raw")
|
|
ap.add_argument("out")
|
|
ap.add_argument("--crop", default=None)
|
|
ap.add_argument("--trim", action="store_true")
|
|
ap.add_argument("--color", action="store_true")
|
|
ap.add_argument("--mean", type=float, default=0.8)
|
|
a = ap.parse_args()
|
|
|
|
img = Image.open(a.raw).convert("RGB")
|
|
if a.crop:
|
|
f = [float(v) for v in a.crop.split(",")]
|
|
img = img.crop((int(f[0] * img.width), int(f[1] * img.height), int(f[2] * img.width), int(f[3] * img.height)))
|
|
if a.trim:
|
|
# the object: everything darker than the white background, a few pixels in
|
|
mask = img.convert("L").point(lambda v: 255 if v < 235 else 0)
|
|
box = mask.getbbox()
|
|
if box:
|
|
img = img.crop((box[0] + 4, box[1] + 4, box[2] - 4, box[3] - 4))
|
|
if not a.color:
|
|
img = ImageOps.grayscale(img).convert("RGB")
|
|
mean = ImageStat.Stat(img.convert("L")).mean[0] / 255
|
|
k = a.mean / max(mean, 0.01)
|
|
img = img.point(lambda v: min(255, int(v * k)))
|
|
img.resize((64, 64), Image.LANCZOS).save(f"{a.out}-64.png")
|
|
small = img.resize((16, 16), Image.BOX)
|
|
small.quantize(colors=8, method=Image.Quantize.MEDIANCUT, dither=Image.Dither.NONE).convert("RGB").save(f"{a.out}-16.png")
|
|
print(f"{a.out}-64.png, {a.out}-16.png")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|