made citf

This commit is contained in:
0x01FE 2024-09-12 10:42:30 -05:00
parent fccdf56188
commit af68d788b0
3 changed files with 99 additions and 26 deletions

105
ctif.py
View File

@ -2,6 +2,7 @@ import logging
import math
import os
from rich.console import Console
from PIL import Image
import pygame as pg
@ -39,12 +40,38 @@ CHARS = list(reversed([
' '
]))
ALL_CHARS = [
u'',
'@',
'?',
'O',
'P',
'o',
'c',
'i',
'.',
' ',
'|',
'/',
'-',
'\\'
]
# Character Text Image Format
class CTIF:
data: list
colors: list
text: str
width: int
height: int
def __init__(self):
pass
def __init__(self, image: Image.Image | None = None):
self.colors = []
self.text = ""
self.width = 0
self.height = 0
if image:
self.convert(image)
def convert(self, image: Image.Image) -> None:
@ -66,12 +93,10 @@ class CTIF:
sb.save('debug/sobel.png')
text_grid_width = w / SCALED_WIDTH
self.width = text_grid_width
text_grind_height = h / SCALED_HEIGHT
pg.init()
font = pg.font.Font(FONT_PATH, 12)
window = pg.display.set_mode((text_grid_width * TEXT_WIDTH, text_grind_height * TEXT_HEIGHT))
self.height = text_grind_height
y_offset = 0
for y in range(math.floor(h / SCALED_HEIGHT)):
@ -81,7 +106,7 @@ class CTIF:
histogram = {}
# Collect the most common char for a group of pixels
colors = []
color = []
for y2 in range(SCALED_HEIGHT):
for x2 in range(SCALED_WIDTH):
@ -103,9 +128,10 @@ class CTIF:
else:
histogram[char] = 1
colors.append(image.getpixel((real_x, real_y)))
color.append(image.getpixel((real_x, real_y)))
color_avg = self._average_colors(colors)
color_avg = filters.average_colors(color)
self.colors.append(color_avg)
# get most common
most_common = None
@ -115,16 +141,12 @@ class CTIF:
score = histogram[char]
most_common = char
rendered_char = font.render(str(most_common), True, color_avg)
window.blit(rendered_char, (x * TEXT_WIDTH, y * TEXT_HEIGHT))
self.text += str(most_common)
x_offset += SCALED_WIDTH
y_offset += SCALED_HEIGHT
pg.display.update()
pg.image.save(window, "render.png")
pg.quit()
# TODO @0x01FE : refactor plz increment by 30 & 60
@ -151,15 +173,50 @@ class CTIF:
else:
return '|'
def _average_colors(self, colors: list):
avg = [0 for x in range(len(colors[0]))]
def render(self) -> None:
console = Console()
for i, (color, char) in enumerate(zip(self.colors, self.text)):
for color in colors:
for i, num in enumerate(color):
avg[i] += num
hex_color = '#%x%x%x' % color
for i, n in enumerate(avg):
avg[i] /= len(colors)
console.print(f'[{hex_color}]{char}', end='')
return avg
if i + 1 % self.width == 0:
print()
def save_image(self, path: str) -> None:
pg.init()
font = pg.font.Font(FONT_PATH, 12)
window = pg.display.set_mode((self.width * TEXT_WIDTH, self.height * TEXT_HEIGHT))
x, y = 0, 0
for (color, char) in zip(self.colors, self.text):
rendered_char = font.render(char, True, color)
window.blit(rendered_char, (x * TEXT_WIDTH, y * TEXT_HEIGHT))
x += 1
if x == self.width:
x = 0
y += 1
pg.display.update()
pg.image.save(window, path)
pg.quit()
def save_citf(self, filename: str) -> None:
# 3 byte for color, byte for char
b = bytes()
for (color, char) in zip(self.colors, self.text):
for n in color:
b += n.to_bytes(1, 'big')
b += ALL_CHARS.index(char).to_bytes(1, 'big')
with open(f'{filename}.citf', 'wb+') as file:
file.write(b)

View File

@ -69,3 +69,16 @@ def sobel(img: Image.Image, gradient_threshold: int | None = 20) -> tuple[Image.
return (newimg, gradient)
def average_colors(colors: list) -> tuple:
colors = np.array(colors)
np.average(colors)
sum = np.zeros(len(colors[0]))
for c in colors:
sum += c
sum /= len(colors)
return tuple(sum.astype(np.uint8).tolist())

View File

@ -1,7 +1,8 @@
import logging
from PIL import Image
import asciify
import ctif
FORMAT = "%(levelname)s %(filename)s - %(message)s"
logging.basicConfig(level=logging.DEBUG, format=FORMAT)
@ -11,7 +12,9 @@ IMAGE_PATH = 'sample-images/engine.PNG'
def main():
image = Image.open(IMAGE_PATH)
asciify.asciify(image)
i = ctif.CTIF(image)
# i.save_image('render.png')
i.save_citf('engine')
if __name__ == '__main__':
main()