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"),
|
||||
]
|
||||
|
||||
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]]
|
||||
|
||||
MAX_DIFF = 3 * 255
|
||||
|
||||
def __init__(self, image: Image.Image):
|
||||
self._img = image.convert("P", palette=Image.ADAPTIVE, colors=16)
|
||||
def __init__(self, image: Image.Image, palette: list[int] | int = Image.ADAPTIVE):
|
||||
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._palette: list[int] = self._img.getpalette() or []
|
||||
if len(self._palette) < 16 * 3:
|
||||
|
@ -57,6 +82,7 @@ class Converter:
|
|||
for oy, line in enumerate(self.PIX_BITS):
|
||||
for ox in range(len(line)):
|
||||
pix = self._imgdata[x + ox, y + oy]
|
||||
assert pix < 16, f"{pix} is too big at {x+ox}:{y+oy}"
|
||||
brightness = self._brightness(pix)
|
||||
if brightness > brightest_l:
|
||||
brightest_l, brightest_i = brightness, pix
|
||||
|
@ -70,6 +96,8 @@ class Converter:
|
|||
|
||||
def _get_block(self, x: int, y: int) -> tuple[int, int, int]:
|
||||
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
|
||||
for oy, line in enumerate(self.PIX_BITS):
|
||||
for ox, bit in enumerate(line):
|
||||
|
@ -95,6 +123,14 @@ class Converter:
|
|||
value >>= 7
|
||||
|
||||
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 self._img.width <= 255 * 2 and self._img.height < 255 * 3:
|
||||
version = 0
|
||||
|
@ -180,12 +216,14 @@ def main():
|
|||
dest="cpi_version",
|
||||
type=int,
|
||||
default=-1,
|
||||
choices=(-1, 0, 1),
|
||||
choices=(-2, -1, 0, 1),
|
||||
help=dedent(
|
||||
"""\
|
||||
Force specific CPI version to be used.
|
||||
Only applies to binary format.
|
||||
Valid versions:
|
||||
-V -2 Uses raw format. No headers, default palette.
|
||||
Used for OBCB-CC project.
|
||||
-V -1 Choose any fitting one
|
||||
For images smaller than 255x255, uses CPIv0
|
||||
-V 0 OG CPI, 255x255 maximum, uncompressed
|
||||
|
@ -282,7 +320,10 @@ def main():
|
|||
else:
|
||||
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")
|
||||
if args.textmode:
|
||||
with open(args.output_path, "w") as fp:
|
||||
|
|
Loading…
Reference in New Issue