diff --git a/resources/preview logos/fromtheshadowslogo.png b/resources/preview logos/fromtheshadowslogo.png new file mode 100644 index 0000000..23b2de2 Binary files /dev/null and b/resources/preview logos/fromtheshadowslogo.png differ diff --git a/resources/bundle preview image template/header.png b/resources/preview logos/header.png similarity index 100% rename from resources/bundle preview image template/header.png rename to resources/preview logos/header.png diff --git a/scripts/add_preview_logo.py b/scripts/add_preview_logo.py new file mode 100644 index 0000000..e0350bf --- /dev/null +++ b/scripts/add_preview_logo.py @@ -0,0 +1,123 @@ +import argparse +import fnmatch +from pathlib import Path + +from PIL import Image + + +def repo_root() -> Path: + return Path(__file__).resolve().parents[1] + + +def default_logo_path() -> Path: + return repo_root() / "resources" / "bundle preview image template" / "header.png" + + +def resolve_path(value: str, base: Path) -> Path: + path = Path(value) + if path.is_absolute(): + return path + return base / path + + +def iter_inputs(patterns: list[str], base: Path) -> list[Path]: + paths: list[Path] = [] + for pattern in patterns: + path = resolve_path(pattern, base) + if any(char in pattern for char in "*?[]"): + matches = sorted(base.glob(pattern)) + elif path.is_dir(): + matches = sorted(path.glob("*.png")) + else: + matches = [path] + for match in matches: + if match.is_file() and match.suffix.lower() in {".png", ".jpg", ".jpeg"} and match not in paths: + paths.append(match) + return paths + + +def is_excluded(path: Path, excludes: list[str], base: Path) -> bool: + if not excludes: + return False + try: + relative = path.relative_to(base).as_posix() + except ValueError: + relative = path.as_posix() + name = path.name + return any(fnmatch.fnmatch(relative, pattern) or fnmatch.fnmatch(name, pattern) for pattern in excludes) + + +def scaled_logo(logo: Image.Image, width: int) -> Image.Image: + height = round(logo.height * width / logo.width) + return logo.resize((width, height), Image.Resampling.LANCZOS) + + +def add_logo( + image_path: Path, + output_path: Path, + logo: Image.Image, + logo_width_ratio: float, + logo_width: int | None, + top: int, + opacity: float, +) -> None: + image = Image.open(image_path).convert("RGBA") + width = logo_width or round(image.width * logo_width_ratio) + overlay = scaled_logo(logo, width) + if opacity < 1: + alpha = overlay.getchannel("A").point(lambda value: round(value * opacity)) + overlay.putalpha(alpha) + x = (image.width - overlay.width) // 2 + image.alpha_composite(overlay, (x, top)) + output_path.parent.mkdir(parents=True, exist_ok=True) + image.save(output_path) + + +def output_for(input_path: Path, input_base: Path, output_dir: Path | None, in_place: bool) -> Path: + if in_place: + return input_path + if output_dir is None: + return input_path.with_name(f"{input_path.stem}_logo{input_path.suffix}") + try: + relative = input_path.relative_to(input_base) + except ValueError: + relative = Path(input_path.name) + return output_dir / relative + + +def main() -> int: + parser = argparse.ArgumentParser(description="Add the Minecraft Legacy4J header logo to preview images.") + parser.add_argument("inputs", nargs="+", help="Files, directories, or glob patterns. Directories process PNG files.") + parser.add_argument("--logo", default=str(default_logo_path()), help="Transparent logo image to overlay.") + parser.add_argument("--input-base", default=str(repo_root()), help="Base path for relative inputs and output layout.") + parser.add_argument("--output-dir", help="Write results under this directory instead of beside inputs.") + parser.add_argument("--in-place", action="store_true", help="Overwrite input files.") + parser.add_argument("--exclude", action="append", default=[], help="Glob pattern to skip. May be repeated.") + parser.add_argument("--logo-width-ratio", type=float, default=0.90, help="Logo width as a fraction of image width.") + parser.add_argument("--logo-width", type=int, help="Fixed logo width in pixels.") + parser.add_argument("--top", type=int, default=19, help="Logo top offset in pixels.") + parser.add_argument("--opacity", type=float, default=1.0, help="Logo opacity from 0.0 to 1.0.") + parser.add_argument("--dry-run", action="store_true", help="Print files that would be written.") + args = parser.parse_args() + + input_base = resolve_path(args.input_base, Path.cwd()).resolve() + logo_path = resolve_path(args.logo, input_base) + output_dir = resolve_path(args.output_dir, input_base) if args.output_dir else None + logo = Image.open(logo_path).convert("RGBA") + paths = iter_inputs(args.inputs, input_base) + if not paths: + raise FileNotFoundError("No input preview images matched.") + for path in paths: + if is_excluded(path, args.exclude, input_base): + continue + out = output_for(path, input_base, output_dir, args.in_place) + if args.dry_run: + print(f"{path} -> {out}") + continue + add_logo(path, out, logo, args.logo_width_ratio, args.logo_width, args.top, args.opacity) + print(out) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/skinpacks/preview_images/adventuretime_preview.png b/skinpacks/preview_images/adventuretime_preview.png index 5d9463f..1cf9a94 100644 Binary files a/skinpacks/preview_images/adventuretime_preview.png and b/skinpacks/preview_images/adventuretime_preview.png differ diff --git a/skinpacks/preview_images/battleandbeasts_preview.png b/skinpacks/preview_images/battleandbeasts_preview.png index 12aa908..f5911b1 100644 Binary files a/skinpacks/preview_images/battleandbeasts_preview.png and b/skinpacks/preview_images/battleandbeasts_preview.png differ diff --git a/skinpacks/preview_images/battleandthebeasts2_preview.png b/skinpacks/preview_images/battleandthebeasts2_preview.png index 20fa24e..513ec47 100644 Binary files a/skinpacks/preview_images/battleandthebeasts2_preview.png and b/skinpacks/preview_images/battleandthebeasts2_preview.png differ diff --git a/skinpacks/preview_images/biomesettlers2_preview.png b/skinpacks/preview_images/biomesettlers2_preview.png index 04cd0a7..dd6bdb3 100644 Binary files a/skinpacks/preview_images/biomesettlers2_preview.png and b/skinpacks/preview_images/biomesettlers2_preview.png differ diff --git a/skinpacks/preview_images/biomesettlers3_preview.png b/skinpacks/preview_images/biomesettlers3_preview.png index 9b02753..ea11118 100644 Binary files a/skinpacks/preview_images/biomesettlers3_preview.png and b/skinpacks/preview_images/biomesettlers3_preview.png differ diff --git a/skinpacks/preview_images/biomesettlers_preview.png b/skinpacks/preview_images/biomesettlers_preview.png index 2704d06..57f04e0 100644 Binary files a/skinpacks/preview_images/biomesettlers_preview.png and b/skinpacks/preview_images/biomesettlers_preview.png differ diff --git a/skinpacks/preview_images/birthday2_preview.png b/skinpacks/preview_images/birthday2_preview.png index 977f87b..9217ffa 100644 Binary files a/skinpacks/preview_images/birthday2_preview.png and b/skinpacks/preview_images/birthday2_preview.png differ diff --git a/skinpacks/preview_images/birthday3_preview.png b/skinpacks/preview_images/birthday3_preview.png index 5e1c46b..3e6141a 100644 Binary files a/skinpacks/preview_images/birthday3_preview.png and b/skinpacks/preview_images/birthday3_preview.png differ diff --git a/skinpacks/preview_images/birthday4_preview.png b/skinpacks/preview_images/birthday4_preview.png index 0e3856f..e1ae138 100644 Binary files a/skinpacks/preview_images/birthday4_preview.png and b/skinpacks/preview_images/birthday4_preview.png differ diff --git a/skinpacks/preview_images/birthday5_preview.png b/skinpacks/preview_images/birthday5_preview.png index 6c82ed9..b5622f5 100644 Binary files a/skinpacks/preview_images/birthday5_preview.png and b/skinpacks/preview_images/birthday5_preview.png differ diff --git a/skinpacks/preview_images/birthday_preview.png b/skinpacks/preview_images/birthday_preview.png index 75681a6..9998e46 100644 Binary files a/skinpacks/preview_images/birthday_preview.png and b/skinpacks/preview_images/birthday_preview.png differ diff --git a/skinpacks/preview_images/campfiretales_preview.png b/skinpacks/preview_images/campfiretales_preview.png index 4619bab..ba2f701 100644 Binary files a/skinpacks/preview_images/campfiretales_preview.png and b/skinpacks/preview_images/campfiretales_preview.png differ diff --git a/skinpacks/preview_images/chinesemythology_preview.png b/skinpacks/preview_images/chinesemythology_preview.png index a59356f..471c2ac 100644 Binary files a/skinpacks/preview_images/chinesemythology_preview.png and b/skinpacks/preview_images/chinesemythology_preview.png differ diff --git a/skinpacks/preview_images/classicskinpack1_preview.png b/skinpacks/preview_images/classicskinpack1_preview.png index 1a8b772..27d5c8f 100644 Binary files a/skinpacks/preview_images/classicskinpack1_preview.png and b/skinpacks/preview_images/classicskinpack1_preview.png differ diff --git a/skinpacks/preview_images/doctor_who_volume_1_preview.png b/skinpacks/preview_images/doctor_who_volume_1_preview.png index d60a740..d369870 100644 Binary files a/skinpacks/preview_images/doctor_who_volume_1_preview.png and b/skinpacks/preview_images/doctor_who_volume_1_preview.png differ diff --git a/skinpacks/preview_images/doctor_who_volume_2_preview.png b/skinpacks/preview_images/doctor_who_volume_2_preview.png index 1b81c21..d369870 100644 Binary files a/skinpacks/preview_images/doctor_who_volume_2_preview.png and b/skinpacks/preview_images/doctor_who_volume_2_preview.png differ diff --git a/skinpacks/preview_images/egyptianmythology_preview.png b/skinpacks/preview_images/egyptianmythology_preview.png index 1771c38..0aaaf5d 100644 Binary files a/skinpacks/preview_images/egyptianmythology_preview.png and b/skinpacks/preview_images/egyptianmythology_preview.png differ diff --git a/skinpacks/preview_images/fallout_preview.png b/skinpacks/preview_images/fallout_preview.png index 3f7301b..e0868d2 100644 Binary files a/skinpacks/preview_images/fallout_preview.png and b/skinpacks/preview_images/fallout_preview.png differ diff --git a/skinpacks/preview_images/festive_preview.png b/skinpacks/preview_images/festive_preview.png index d637d4e..104f55a 100644 Binary files a/skinpacks/preview_images/festive_preview.png and b/skinpacks/preview_images/festive_preview.png differ diff --git a/skinpacks/preview_images/festivemashup_preview.png b/skinpacks/preview_images/festivemashup_preview.png index f6b698e..b01e934 100644 Binary files a/skinpacks/preview_images/festivemashup_preview.png and b/skinpacks/preview_images/festivemashup_preview.png differ diff --git a/skinpacks/preview_images/finalfantasyxv_preview.png b/skinpacks/preview_images/finalfantasyxv_preview.png index 49a244c..c81e854 100644 Binary files a/skinpacks/preview_images/finalfantasyxv_preview.png and b/skinpacks/preview_images/finalfantasyxv_preview.png differ diff --git a/skinpacks/preview_images/fromtheshadows_preview.png b/skinpacks/preview_images/fromtheshadows_preview.png index e14836a..1a5a3fc 100644 Binary files a/skinpacks/preview_images/fromtheshadows_preview.png and b/skinpacks/preview_images/fromtheshadows_preview.png differ diff --git a/skinpacks/preview_images/greekmythology_preview.png b/skinpacks/preview_images/greekmythology_preview.png index 51346e2..e738177 100644 Binary files a/skinpacks/preview_images/greekmythology_preview.png and b/skinpacks/preview_images/greekmythology_preview.png differ diff --git a/skinpacks/preview_images/halloween2015_preview.png b/skinpacks/preview_images/halloween2015_preview.png index d6059a6..5fc14fd 100644 Binary files a/skinpacks/preview_images/halloween2015_preview.png and b/skinpacks/preview_images/halloween2015_preview.png differ diff --git a/skinpacks/preview_images/halloweencharity_preview.png b/skinpacks/preview_images/halloweencharity_preview.png index 93678b4..ed8ee70 100644 Binary files a/skinpacks/preview_images/halloweencharity_preview.png and b/skinpacks/preview_images/halloweencharity_preview.png differ diff --git a/skinpacks/preview_images/halo_preview.png b/skinpacks/preview_images/halo_preview.png index 3540fb6..67d7ab4 100644 Binary files a/skinpacks/preview_images/halo_preview.png and b/skinpacks/preview_images/halo_preview.png differ diff --git a/skinpacks/preview_images/littlebigplanet_preview.png b/skinpacks/preview_images/littlebigplanet_preview.png index 2ec6267..80363c4 100644 Binary files a/skinpacks/preview_images/littlebigplanet_preview.png and b/skinpacks/preview_images/littlebigplanet_preview.png differ diff --git a/skinpacks/preview_images/magicthegathering_preview.png b/skinpacks/preview_images/magicthegathering_preview.png index e84189f..fdbfde4 100644 Binary files a/skinpacks/preview_images/magicthegathering_preview.png and b/skinpacks/preview_images/magicthegathering_preview.png differ diff --git a/skinpacks/preview_images/marvelgog_preview.png b/skinpacks/preview_images/marvelgog_preview.png index c515f8a..7b82ef2 100644 Binary files a/skinpacks/preview_images/marvelgog_preview.png and b/skinpacks/preview_images/marvelgog_preview.png differ diff --git a/skinpacks/preview_images/marvelsavengers_preview.png b/skinpacks/preview_images/marvelsavengers_preview.png index 536e54c..13eb6cb 100644 Binary files a/skinpacks/preview_images/marvelsavengers_preview.png and b/skinpacks/preview_images/marvelsavengers_preview.png differ diff --git a/skinpacks/preview_images/marvelsspiderman_preview.png b/skinpacks/preview_images/marvelsspiderman_preview.png index 982554e..d1515e1 100644 Binary files a/skinpacks/preview_images/marvelsspiderman_preview.png and b/skinpacks/preview_images/marvelsspiderman_preview.png differ diff --git a/skinpacks/preview_images/masseffect_preview.png b/skinpacks/preview_images/masseffect_preview.png index 46c290a..f0bda99 100644 Binary files a/skinpacks/preview_images/masseffect_preview.png and b/skinpacks/preview_images/masseffect_preview.png differ diff --git a/skinpacks/preview_images/minecon2015_preview.png b/skinpacks/preview_images/minecon2015_preview.png index 6ad023a..ecc2f37 100644 Binary files a/skinpacks/preview_images/minecon2015_preview.png and b/skinpacks/preview_images/minecon2015_preview.png differ diff --git a/skinpacks/preview_images/minecon2016_preview.png b/skinpacks/preview_images/minecon2016_preview.png index a39b51e..67b6404 100644 Binary files a/skinpacks/preview_images/minecon2016_preview.png and b/skinpacks/preview_images/minecon2016_preview.png differ diff --git a/skinpacks/preview_images/minecon2017_preview.png b/skinpacks/preview_images/minecon2017_preview.png index 4f22aa3..eedcd10 100644 Binary files a/skinpacks/preview_images/minecon2017_preview.png and b/skinpacks/preview_images/minecon2017_preview.png differ diff --git a/skinpacks/preview_images/minigameheros_preview.png b/skinpacks/preview_images/minigameheros_preview.png index b22cd0a..f57a618 100644 Binary files a/skinpacks/preview_images/minigameheros_preview.png and b/skinpacks/preview_images/minigameheros_preview.png differ diff --git a/skinpacks/preview_images/minigamemasters_preview.png b/skinpacks/preview_images/minigamemasters_preview.png index 387bc02..9f4e69f 100644 Binary files a/skinpacks/preview_images/minigamemasters_preview.png and b/skinpacks/preview_images/minigamemasters_preview.png differ diff --git a/skinpacks/preview_images/moana_preview.png b/skinpacks/preview_images/moana_preview.png index 919e4f1..cc13a00 100644 Binary files a/skinpacks/preview_images/moana_preview.png and b/skinpacks/preview_images/moana_preview.png differ diff --git a/skinpacks/preview_images/norsemythology_preview.png b/skinpacks/preview_images/norsemythology_preview.png index 88b827f..96e7475 100644 Binary files a/skinpacks/preview_images/norsemythology_preview.png and b/skinpacks/preview_images/norsemythology_preview.png differ diff --git a/skinpacks/preview_images/piratesofthecaribbean_preview.png b/skinpacks/preview_images/piratesofthecaribbean_preview.png index 21df71c..d5de855 100644 Binary files a/skinpacks/preview_images/piratesofthecaribbean_preview.png and b/skinpacks/preview_images/piratesofthecaribbean_preview.png differ diff --git a/skinpacks/preview_images/powerrangers_preview.png b/skinpacks/preview_images/powerrangers_preview.png index 6ab9404..8e71ea0 100644 Binary files a/skinpacks/preview_images/powerrangers_preview.png and b/skinpacks/preview_images/powerrangers_preview.png differ diff --git a/skinpacks/preview_images/redstonespecialists_preview.png b/skinpacks/preview_images/redstonespecialists_preview.png index 5f0326a..f36ec72 100644 Binary files a/skinpacks/preview_images/redstonespecialists_preview.png and b/skinpacks/preview_images/redstonespecialists_preview.png differ diff --git a/skinpacks/preview_images/skinpack1_preview.png b/skinpacks/preview_images/skinpack1_preview.png index 6ad6cff..8409219 100644 Binary files a/skinpacks/preview_images/skinpack1_preview.png and b/skinpacks/preview_images/skinpack1_preview.png differ diff --git a/skinpacks/preview_images/skinpack2_preview.png b/skinpacks/preview_images/skinpack2_preview.png index 1e49d33..c011e6f 100644 Binary files a/skinpacks/preview_images/skinpack2_preview.png and b/skinpacks/preview_images/skinpack2_preview.png differ diff --git a/skinpacks/preview_images/skinpack3_preview.png b/skinpacks/preview_images/skinpack3_preview.png index 4911fc9..9af9e08 100644 Binary files a/skinpacks/preview_images/skinpack3_preview.png and b/skinpacks/preview_images/skinpack3_preview.png differ diff --git a/skinpacks/preview_images/skinpack4_preview.png b/skinpacks/preview_images/skinpack4_preview.png index d164f21..e8bfe92 100644 Binary files a/skinpacks/preview_images/skinpack4_preview.png and b/skinpacks/preview_images/skinpack4_preview.png differ diff --git a/skinpacks/preview_images/skinpack5_preview.png b/skinpacks/preview_images/skinpack5_preview.png index e82d797..5784cb6 100644 Binary files a/skinpacks/preview_images/skinpack5_preview.png and b/skinpacks/preview_images/skinpack5_preview.png differ diff --git a/skinpacks/preview_images/skinpack6_preview.png b/skinpacks/preview_images/skinpack6_preview.png index cb069af..1ab4d1b 100644 Binary files a/skinpacks/preview_images/skinpack6_preview.png and b/skinpacks/preview_images/skinpack6_preview.png differ diff --git a/skinpacks/preview_images/skyrim_preview.png b/skinpacks/preview_images/skyrim_preview.png index c4159a8..9a6db8e 100644 Binary files a/skinpacks/preview_images/skyrim_preview.png and b/skinpacks/preview_images/skyrim_preview.png differ diff --git a/skinpacks/preview_images/soa_preview.png b/skinpacks/preview_images/soa_preview.png index 7506168..72ca611 100644 Binary files a/skinpacks/preview_images/soa_preview.png and b/skinpacks/preview_images/soa_preview.png differ diff --git a/skinpacks/preview_images/starwarsclassic_preview.png b/skinpacks/preview_images/starwarsclassic_preview.png index 3a6ce07..f7b3f3d 100644 Binary files a/skinpacks/preview_images/starwarsclassic_preview.png and b/skinpacks/preview_images/starwarsclassic_preview.png differ diff --git a/skinpacks/preview_images/starwarsprequel_preview.png b/skinpacks/preview_images/starwarsprequel_preview.png index 8978607..0058674 100644 Binary files a/skinpacks/preview_images/starwarsprequel_preview.png and b/skinpacks/preview_images/starwarsprequel_preview.png differ diff --git a/skinpacks/preview_images/starwarsrebels_preview.png b/skinpacks/preview_images/starwarsrebels_preview.png index 3843b8a..ff3e752 100644 Binary files a/skinpacks/preview_images/starwarsrebels_preview.png and b/skinpacks/preview_images/starwarsrebels_preview.png differ diff --git a/skinpacks/preview_images/starwarssequel_preview.png b/skinpacks/preview_images/starwarssequel_preview.png index 3443660..9cbcd6d 100644 Binary files a/skinpacks/preview_images/starwarssequel_preview.png and b/skinpacks/preview_images/starwarssequel_preview.png differ diff --git a/skinpacks/preview_images/starwarssolo_preview.png b/skinpacks/preview_images/starwarssolo_preview.png index f482066..ae69bdc 100644 Binary files a/skinpacks/preview_images/starwarssolo_preview.png and b/skinpacks/preview_images/starwarssolo_preview.png differ diff --git a/skinpacks/preview_images/stevenuniverse_preview.png b/skinpacks/preview_images/stevenuniverse_preview.png index af50dbf..375dc7a 100644 Binary files a/skinpacks/preview_images/stevenuniverse_preview.png and b/skinpacks/preview_images/stevenuniverse_preview.png differ diff --git a/skinpacks/preview_images/storymode_preview.png b/skinpacks/preview_images/storymode_preview.png index 985707d..5d367e5 100644 Binary files a/skinpacks/preview_images/storymode_preview.png and b/skinpacks/preview_images/storymode_preview.png differ diff --git a/skinpacks/preview_images/strangerthings_preview.png b/skinpacks/preview_images/strangerthings_preview.png index 385c802..3fb66e5 100644 Binary files a/skinpacks/preview_images/strangerthings_preview.png and b/skinpacks/preview_images/strangerthings_preview.png differ diff --git a/skinpacks/preview_images/supercuteskins_preview.png b/skinpacks/preview_images/supercuteskins_preview.png index 0f3af52..498c8b7 100644 Binary files a/skinpacks/preview_images/supercuteskins_preview.png and b/skinpacks/preview_images/supercuteskins_preview.png differ diff --git a/skinpacks/preview_images/theincredibles_preview.png b/skinpacks/preview_images/theincredibles_preview.png index ebccfe3..b95dfc2 100644 Binary files a/skinpacks/preview_images/theincredibles_preview.png and b/skinpacks/preview_images/theincredibles_preview.png differ diff --git a/skinpacks/preview_images/thenightmarebeforechristmas_preview.png b/skinpacks/preview_images/thenightmarebeforechristmas_preview.png index 039f5c6..1a0bc2b 100644 Binary files a/skinpacks/preview_images/thenightmarebeforechristmas_preview.png and b/skinpacks/preview_images/thenightmarebeforechristmas_preview.png differ diff --git a/skinpacks/preview_images/thesimpsons_preview.png b/skinpacks/preview_images/thesimpsons_preview.png index 1ea547b..47b8df6 100644 Binary files a/skinpacks/preview_images/thesimpsons_preview.png and b/skinpacks/preview_images/thesimpsons_preview.png differ diff --git a/skinpacks/preview_images/villians_preview.png b/skinpacks/preview_images/villians_preview.png index 0eef16f..587f7a0 100644 Binary files a/skinpacks/preview_images/villians_preview.png and b/skinpacks/preview_images/villians_preview.png differ