Added palette support

This commit is contained in:
Casey 2024-09-13 03:33:52 +03:00
parent 712346e2c5
commit a3b079e638
Signed by: hkc
GPG Key ID: F0F6CFE11CDB0960
1 changed files with 71 additions and 3 deletions

View File

@ -1,11 +1,16 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from typing import BinaryIO, TextIO from typing import BinaryIO, TextIO
from PIL import Image from PIL import Image, ImageColor
from argparse import ArgumentParser, RawTextHelpFormatter from argparse import ArgumentParser, RawTextHelpFormatter
from textwrap import dedent from textwrap import dedent
from functools import lru_cache from functools import lru_cache
try:
PALETTE_ADAPTIVE = Image.Palette.ADAPTIVE
except Exception:
PALETTE_ADAPTIVE = Image.ADAPTIVE
class Converter: class Converter:
CC_COLORS = [ CC_COLORS = [
@ -46,11 +51,30 @@ class Converter:
17, 17, 17 17, 17, 17
] ]
DEFAULT_GRAYSCALE_PALETTE = [
0xf0, 0xf0, 0xf0,
0x9d, 0x9d, 0x9d,
0xbe, 0xbe, 0xbe,
0xbf, 0xbf, 0xbf,
0xb8, 0xb8, 0xb8,
0x76, 0x76, 0x76,
0xd0, 0xd0, 0xd0,
0x4c, 0x4c, 0x4c,
0x99, 0x99, 0x99,
0x87, 0x87, 0x87,
0xa9, 0xa9, 0xa9,
0x77, 0x77, 0x77,
0x65, 0x65, 0x65,
0x6e, 0x6e, 0x6e,
0x76, 0x76, 0x76,
0x11, 0x11, 0x11
]
PIX_BITS = [[1, 2], [4, 8], [16, 0]] PIX_BITS = [[1, 2], [4, 8], [16, 0]]
MAX_DIFF = 3 * 255 MAX_DIFF = 3 * 255
def __init__(self, image: Image.Image, palette: list[int] | int = Image.ADAPTIVE): def __init__(self, image: Image.Image, palette: list[int] | int = PALETTE_ADAPTIVE):
if isinstance(palette, list): if isinstance(palette, list):
img_pal = Image.new("P", (1, 1)) img_pal = Image.new("P", (1, 1))
img_pal.putpalette(palette) img_pal.putpalette(palette)
@ -246,6 +270,25 @@ def main():
-p fill Stretch to fill""" -p fill Stretch to fill"""
), ),
) )
parser.add_argument(
"-P",
dest="palette",
default="auto",
help=dedent(
"""\
Palette to be used for that conversion.
Should be 16 colors or less
Valid options are:
-P auto Determine palette automatically
-P default Use default CC:Tweaked color palette
-P defaultgray Use default CC:Tweaked grayscale palette
-P "list:#RRGGBB,#RRGGBB,..." Use a set list of colors
-P "cpi:path" Load palette from a CCPI file
-P "gpl:path" Parse GIMP palette file and use first 16 colors
-P "txt:path" Load palette from a list of hex values
"""
)
)
parser.add_argument("image_path") parser.add_argument("image_path")
parser.add_argument("output_path") parser.add_argument("output_path")
@ -320,9 +363,34 @@ def main():
else: else:
pass pass
palette = Image.Palette.ADAPTIVE palette = PALETTE_ADAPTIVE
if args.cpi_version == -2: if args.cpi_version == -2:
args.palette = "default"
if args.palette == "auto":
palette = PALETTE_ADAPTIVE
elif args.palette == "default":
palette = Converter.DEFAULT_PALETTE palette = Converter.DEFAULT_PALETTE
elif args.palette == "defaultgray":
palette = Converter.DEFAULT_GRAYSCALE_PALETTE
elif args.palette.startswith("txt:"):
with open(args.palette[4:], "r") as fp:
palette = []
for line in fp:
palette += ImageColor.getcolor(line.strip(), "RGB") # type: ignore
assert len(palette) <= 16 * 3
elif args.palette.startswith("list:"):
palette = []
for c in args.palette[5:].split(","):
palette += ImageColor.getcolor(c, "RGB") # type: ignore
assert len(palette) <= 16 * 3
elif args.palette.startswith("cpi:"):
raise ValueError("not implemented yet")
elif args.palette.startswith("gpl:"):
raise ValueError("not implemented yet")
else:
raise ValueError(f"invalid palette identifier: {args.palette!r}")
converter = Converter(canv, palette) converter = Converter(canv, palette)
converter._img.save("/tmp/_ccpictmp.png") converter._img.save("/tmp/_ccpictmp.png")
if args.textmode: if args.textmode: