Skip to content

Instantly share code, notes, and snippets.

@idbrii
Created March 8, 2024 07:18
Show Gist options
  • Save idbrii/2654379b468479e6542092e280d7d814 to your computer and use it in GitHub Desktop.
Save idbrii/2654379b468479e6542092e280d7d814 to your computer and use it in GitHub Desktop.
Download and convert a lospec url to a Paint.NET palette.
#! /usr/bin/env python
"""
Download and convert a lospec url to a Paint.NET palette.
CC0
"""
import argparse
import tempfile
import urllib.request
from pathlib import Path
MAX_COLORS = 96
def convert_palette(c):
colours = c.strip().split()
c_per_row = 16
occupied_slots = c_per_row
n_colours = len(colours)
while occupied_slots < n_colours:
occupied_slots += c_per_row
# Add white to always start palette in first column.
colours += ["FFFFFF"] * (occupied_slots - n_colours)
# Choose variants based on how much space we have. Max 96 colours.
alpha_variants = []
n_variants = MAX_COLORS // len(colours)
stride = 0x11 * (16 // n_variants)
a = 0xFF
while n_variants > 0:
n_variants -= 1
alpha_variants.append("{a:02X}".format(a=a))
a -= stride
return "\n".join([alpha + line for alpha in alpha_variants for line in colours])
def _parse_args():
arg_parser = argparse.ArgumentParser(
description="""Create a Paint.NET palette from lospec.""",
formatter_class=argparse.RawDescriptionHelpFormatter,
)
arg_parser.add_argument(
"--url",
help="The url of the palette.",
type=str,
required=True,
)
arg_parser.add_argument(
"--output-folder",
type=Path,
help="Where to write the palette. <path to paint>/UserFiles/Palettes/. Defaults to path for paint installed with scoop.",
)
arg_parser.add_argument(
"--output-name",
type=str,
help="Name of the output palette. Defaults to name from url.",
)
args = arg_parser.parse_args()
if not args.url.endswith(".hex"):
args.url += ".hex"
i = args.url.rfind("/")
name = args.url[i + 1 : -4] + ".txt"
if not args.output_name:
args.output_name = name
if not args.output_folder:
args.output_folder = (
Path.home() / "scoop/apps/paint.net/current/UserFiles/Palettes/"
)
print(
"Guessing scoop install. Selected output folder:",
args.output_folder.as_posix(),
)
return args
def main(args):
with tempfile.TemporaryDirectory() as tmpdir:
tmp = Path(tmpdir) / "hex.txt"
# Get the normal page first since it fails immediately if invalid.
# Downloading the hex page may hang for a long time if you made a typo
urllib.request.urlretrieve(args.url[:-4], tmp)
urllib.request.urlretrieve(args.url, tmp) # hex
palette = convert_palette(tmp.read_text())
output_file = args.output_folder / args.output_name
print("Writing palette:", output_file.as_posix())
output_file.write_text(palette)
if __name__ == "__main__":
main(_parse_args())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment