forked from hkc/cc-stuff
Added raw format
This commit is contained in:
parent
bf3c5e6b1c
commit
710699f5cb
49
cc-pic.py
49
cc-pic.py
|
@ -27,12 +27,37 @@ class Converter:
|
||||||
("f", "colors.black"),
|
("f", "colors.black"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
DEFAULT_PALETTE = [
|
||||||
|
240, 240, 240,
|
||||||
|
242, 178, 51,
|
||||||
|
229, 127, 216,
|
||||||
|
153, 178, 242,
|
||||||
|
222, 222, 108,
|
||||||
|
127, 204, 25,
|
||||||
|
242, 178, 204,
|
||||||
|
76, 76, 76,
|
||||||
|
153, 153, 153,
|
||||||
|
76, 153, 178,
|
||||||
|
178, 102, 229,
|
||||||
|
51, 102, 204,
|
||||||
|
127, 102, 76,
|
||||||
|
87, 166, 78,
|
||||||
|
204, 76, 76,
|
||||||
|
17, 17, 17
|
||||||
|
]
|
||||||
|
|
||||||
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):
|
def __init__(self, image: Image.Image, palette: list[int] | int = Image.ADAPTIVE):
|
||||||
self._img = image.convert("P", palette=Image.ADAPTIVE, colors=16)
|
if isinstance(palette, list):
|
||||||
|
img_pal = Image.new("P", (1, 1))
|
||||||
|
img_pal.putpalette(palette)
|
||||||
|
self._img = image.quantize(16, palette=img_pal)
|
||||||
|
else:
|
||||||
|
self._img = image.convert("P", palette=palette, colors=16)
|
||||||
|
|
||||||
self._imgdata = self._img.load()
|
self._imgdata = self._img.load()
|
||||||
self._palette: list[int] = self._img.getpalette() or []
|
self._palette: list[int] = self._img.getpalette() or []
|
||||||
if len(self._palette) < 16 * 3:
|
if len(self._palette) < 16 * 3:
|
||||||
|
@ -57,6 +82,7 @@ class Converter:
|
||||||
for oy, line in enumerate(self.PIX_BITS):
|
for oy, line in enumerate(self.PIX_BITS):
|
||||||
for ox in range(len(line)):
|
for ox in range(len(line)):
|
||||||
pix = self._imgdata[x + ox, y + oy]
|
pix = self._imgdata[x + ox, y + oy]
|
||||||
|
assert pix < 16, f"{pix} is too big at {x+ox}:{y+oy}"
|
||||||
brightness = self._brightness(pix)
|
brightness = self._brightness(pix)
|
||||||
if brightness > brightest_l:
|
if brightness > brightest_l:
|
||||||
brightest_l, brightest_i = brightness, pix
|
brightest_l, brightest_i = brightness, pix
|
||||||
|
@ -70,6 +96,8 @@ class Converter:
|
||||||
|
|
||||||
def _get_block(self, x: int, y: int) -> tuple[int, int, int]:
|
def _get_block(self, x: int, y: int) -> tuple[int, int, int]:
|
||||||
dark_i, bri_i = self._get_colors(x, y)
|
dark_i, bri_i = self._get_colors(x, y)
|
||||||
|
assert dark_i < 16, f"{dark_i} is too big"
|
||||||
|
assert bri_i < 16, f"{bri_i} is too big"
|
||||||
out: int = 0
|
out: int = 0
|
||||||
for oy, line in enumerate(self.PIX_BITS):
|
for oy, line in enumerate(self.PIX_BITS):
|
||||||
for ox, bit in enumerate(line):
|
for ox, bit in enumerate(line):
|
||||||
|
@ -95,6 +123,14 @@ class Converter:
|
||||||
value >>= 7
|
value >>= 7
|
||||||
|
|
||||||
def export_binary(self, io: BinaryIO, version: int = -1):
|
def export_binary(self, io: BinaryIO, version: int = -1):
|
||||||
|
if version == -2:
|
||||||
|
for y in range(0, self._img.height - 2, 3):
|
||||||
|
line: bytearray = bytearray()
|
||||||
|
for x in range(0, self._img.width - 1, 2):
|
||||||
|
ch, bg, fg = self._get_block(x, y)
|
||||||
|
line.extend([(ch + 0x80) & 0xFF, fg << 4 | bg])
|
||||||
|
io.write(line)
|
||||||
|
return
|
||||||
if version == -1:
|
if version == -1:
|
||||||
if self._img.width <= 255 * 2 and self._img.height < 255 * 3:
|
if self._img.width <= 255 * 2 and self._img.height < 255 * 3:
|
||||||
version = 0
|
version = 0
|
||||||
|
@ -180,12 +216,14 @@ def main():
|
||||||
dest="cpi_version",
|
dest="cpi_version",
|
||||||
type=int,
|
type=int,
|
||||||
default=-1,
|
default=-1,
|
||||||
choices=(-1, 0, 1),
|
choices=(-2, -1, 0, 1),
|
||||||
help=dedent(
|
help=dedent(
|
||||||
"""\
|
"""\
|
||||||
Force specific CPI version to be used.
|
Force specific CPI version to be used.
|
||||||
Only applies to binary format.
|
Only applies to binary format.
|
||||||
Valid versions:
|
Valid versions:
|
||||||
|
-V -2 Uses raw format. No headers, default palette.
|
||||||
|
Used for OBCB-CC project.
|
||||||
-V -1 Choose any fitting one
|
-V -1 Choose any fitting one
|
||||||
For images smaller than 255x255, uses CPIv0
|
For images smaller than 255x255, uses CPIv0
|
||||||
-V 0 OG CPI, 255x255 maximum, uncompressed
|
-V 0 OG CPI, 255x255 maximum, uncompressed
|
||||||
|
@ -282,7 +320,10 @@ def main():
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
converter = Converter(canv)
|
palette = Image.Palette.ADAPTIVE
|
||||||
|
if args.cpi_version == -2:
|
||||||
|
palette = Converter.DEFAULT_PALETTE
|
||||||
|
converter = Converter(canv, palette)
|
||||||
converter._img.save("/tmp/_ccpictmp.png")
|
converter._img.save("/tmp/_ccpictmp.png")
|
||||||
if args.textmode:
|
if args.textmode:
|
||||||
with open(args.output_path, "w") as fp:
|
with open(args.output_path, "w") as fp:
|
||||||
|
|
Loading…
Reference in New Issue