Solidify unit sprite readability
This commit is contained in:
67
scripts/solidify-unit-alpha.py
Normal file
67
scripts/solidify-unit-alpha.py
Normal file
@@ -0,0 +1,67 @@
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image, ImageChops, ImageFilter, ImageStat
|
||||
from PIL.PngImagePlugin import PngInfo
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
UNIT_DIR = ROOT / "src" / "assets" / "images" / "units"
|
||||
PROCESSING_VERSION = "solid-alpha-silhouette-v1"
|
||||
|
||||
|
||||
def solid_alpha(value: int) -> int:
|
||||
return 0 if value < 16 else 255
|
||||
|
||||
|
||||
def unit_fill_color(image: Image.Image, mask: Image.Image) -> tuple[int, int, int, int]:
|
||||
stat = ImageStat.Stat(image.convert("RGB"), mask=mask)
|
||||
if not stat.count[0]:
|
||||
return (54, 45, 34, 255)
|
||||
|
||||
red, green, blue = stat.mean
|
||||
return (max(30, round(red * 0.45)), max(26, round(green * 0.45)), max(22, round(blue * 0.45)), 255)
|
||||
|
||||
|
||||
def solidify_image(image: Image.Image) -> Image.Image:
|
||||
image = image.convert("RGBA")
|
||||
red, green, blue, alpha = image.split()
|
||||
fixed_alpha = alpha.point(solid_alpha)
|
||||
solid = Image.merge("RGBA", (red, green, blue, fixed_alpha))
|
||||
transparent = Image.new("RGBA", image.size, (0, 0, 0, 0))
|
||||
solid = Image.composite(solid, transparent, fixed_alpha)
|
||||
|
||||
silhouette = fixed_alpha.filter(ImageFilter.MaxFilter(15)).filter(ImageFilter.MinFilter(7))
|
||||
silhouette = silhouette.point(lambda value: 255 if value >= 255 else 0)
|
||||
fill_mask = ImageChops.subtract(silhouette, fixed_alpha)
|
||||
fill = Image.new("RGBA", image.size, unit_fill_color(image, fixed_alpha))
|
||||
body = Image.composite(fill, transparent, fill_mask)
|
||||
return Image.alpha_composite(body, solid)
|
||||
|
||||
|
||||
def solidify_unit_alpha(path: Path) -> bool:
|
||||
with Image.open(path) as source:
|
||||
if source.info.get("heros_unit_alpha") == PROCESSING_VERSION:
|
||||
return False
|
||||
image = source.convert("RGBA")
|
||||
fixed = solidify_image(image)
|
||||
|
||||
if ImageChops.difference(image, fixed).getbbox() is None:
|
||||
return False
|
||||
|
||||
png_info = PngInfo()
|
||||
png_info.add_text("heros_unit_alpha", PROCESSING_VERSION)
|
||||
fixed.save(path, optimize=True, pnginfo=png_info)
|
||||
return True
|
||||
|
||||
|
||||
def main() -> None:
|
||||
changed = 0
|
||||
for path in sorted(UNIT_DIR.glob("unit-*.png")):
|
||||
if solidify_unit_alpha(path):
|
||||
changed += 1
|
||||
|
||||
print(f"Solidified alpha in {changed} unit sprite sheets.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user