Refactor colorizer

Colorizer was a class-based thing but it doesn't really need to be,
because everything is colorized using palettes. If we need to use a
different style of colorization in the future, we will bring the
colorizer class back.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2024-06-03 11:24:31 -07:00
parent c416c24a9c
commit ca2aa4ca3b
5 changed files with 66 additions and 93 deletions

View File

@@ -5,7 +5,7 @@ from pathlib import Path
import sys import sys
import textwrap import textwrap
from .colorizer import PaletteColorizer from .color import colorize
from .matricizer import Matricizer, NibbleMatricizer, RandomartMatricizer from .matricizer import Matricizer, NibbleMatricizer, RandomartMatricizer
from .palettes import Palette, DEFAULT_PALETTES, PALETTES from .palettes import Palette, DEFAULT_PALETTES, PALETTES
from .writer import ANSIWriter, SVGWriter, Writer from .writer import ANSIWriter, SVGWriter, Writer
@@ -16,6 +16,7 @@ from .writer import ANSIWriter, SVGWriter, Writer
# TODO - option to add a caption based on the filename (for SVG) # TODO - option to add a caption based on the filename (for SVG)
# TODO - load palettes from a file # TODO - load palettes from a file
# TODO - PNG output # TODO - PNG output
# TODO - fix Matricizer.choose_dimensions - either get rid of it or use it
def cli_main() -> None: def cli_main() -> None:
@@ -191,12 +192,9 @@ def cli_main() -> None:
else: else:
palette = PALETTES[args.palette] palette = PALETTES[args.palette]
# Choose the colorizer # Matricize and colorize
colorizer = PaletteColorizer(palette)
# Print SVG
matrix = matricizer.matricize(hashdata) matrix = matricizer.matricize(hashdata)
colors = colorizer.colorize(matrix) colors = colorize(palette, matrix)
# Choose the output writer # Choose the output writer
writer: Writer writer: Writer

View File

@@ -1,6 +1,12 @@
import abc import abc
import colorsys import colorsys
import dataclasses import dataclasses
from typing import Sequence, TYPE_CHECKING
if TYPE_CHECKING:
from .palettes import Palette
from .matricizer import Matrix
class Color(metaclass=abc.ABCMeta): class Color(metaclass=abc.ABCMeta):
@@ -33,6 +39,7 @@ class RGBColor(Color):
""" """
An RGB color. Colors are expected to be a floating point value from [0.0-255.0). An RGB color. Colors are expected to be a floating point value from [0.0-255.0).
""" """
r: float r: float
g: float g: float
b: float b: float
@@ -68,6 +75,13 @@ class HSLColor(Color):
r, g, b = colorsys.hls_to_rgb(h, l, s) r, g, b = colorsys.hls_to_rgb(h, l, s)
return RGBColor(r * 255.0, g * 255.0, b * 255.0) return RGBColor(r * 255.0, g * 255.0, b * 255.0)
def to_hsl(self) -> "HSLColor": def to_hsl(self) -> "HSLColor":
return self return self
ColorMatrix = Sequence[Sequence[Color]]
def colorize(palette: "Palette", matrix: "Matrix") -> ColorMatrix:
"Converts a matrix of values from [0x0..0xf] to a matrix of colors."
return [[palette[v] for v in row] for row in matrix]

View File

@@ -1,5 +1,4 @@
"All things that turn a numeric matrix into a colored matrix." "All things that turn a numeric matrix into a colored matrix."
import abc
from typing import Sequence from typing import Sequence
from .color import Color from .color import Color
@@ -10,43 +9,5 @@ from .palettes import Palette
ColorMatrix = Sequence[Sequence[Color]] ColorMatrix = Sequence[Sequence[Color]]
class Colorizer(metaclass=abc.ABCMeta): def colorize(palette: Palette, matrix: Matrix) -> ColorMatrix:
""" return [[palette[v] for v in row] for row in matrix]
The base Colorizer class.
A colorizer turns a numeric matrix into a color matrix, colors being represented by strings of
HTML colors.
"""
@abc.abstractmethod
def colorize(self, matrix: Matrix) -> ColorMatrix:
"""
Colorize a matrix.
:param matrix: the matrix to colorize.
:returns: the colorized matrix.
"""
class PaletteColorizer(Colorizer):
"""
A palette colorizer.
This colorizer will use a palette to colorize its inputs. A palette is 16 colors.
"""
def __init__(self, palette: Palette) -> None:
"""
Create a new palette colorizer for a given palette.
:param palette: the palette to use for this colorizer.
"""
self.palette = palette
def colorize(self, matrix: Matrix) -> ColorMatrix:
"""
Colorize the given matrix using this colorizer's palette.
:param matrix: the matrix to colorize.
:returns: the colorized matrix.
"""
return [[self.palette[v] for v in row] for row in matrix]

View File

@@ -1,7 +1,6 @@
import abc import abc
from .color import Color from .color import Color, ColorMatrix
from .colorizer import ColorMatrix
class Writer(metaclass=abc.ABCMeta): class Writer(metaclass=abc.ABCMeta):
@@ -19,13 +18,15 @@ class Writer(metaclass=abc.ABCMeta):
class ANSIWriter(Writer): class ANSIWriter(Writer):
def write(self, matrix: ColorMatrix) -> str: def write(self, matrix: ColorMatrix) -> str:
ESC = '\x1b' ESC = "\x1b"
RESET = f"{ESC}[0m" RESET = f"{ESC}[0m"
C = "██" C = "██"
def ansi_color(c: Color) -> str: def ansi_color(c: Color) -> str:
c = c.to_rgb() c = c.to_rgb()
return f"{ESC}[38;2;{round(c.r)};{round(c.g)};{round(c.b)}m" return f"{ESC}[38;2;{round(c.r)};{round(c.g)};{round(c.b)}m"
out = ''
out = ""
for row in matrix: for row in matrix:
for col in row: for col in row:
out += ansi_color(col) out += ansi_color(col)
@@ -68,4 +69,3 @@ class SVGWriter(Writer):
# Close SVG string # Close SVG string
svg += "</svg>" svg += "</svg>"
return svg return svg

View File

@@ -1,42 +1,42 @@
<svg width="256" height="160" xmlns="http://www.w3.org/2000/svg"> <svg width="256" height="160" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="32" height="32" fill="hsl(180.00,100.00%,20.00%)" /> <rect x="0" y="0" width="32" height="32" fill="hsl(330.00,100.00%,90.00%)" />
<rect x="32" y="0" width="32" height="32" fill="hsl(180.00,100.00%,0.00%)" /> <rect x="32" y="0" width="32" height="32" fill="hsl(330.00,100.00%,63.33%)" />
<rect x="64" y="0" width="32" height="32" fill="hsl(180.00,100.00%,30.00%)" /> <rect x="64" y="0" width="32" height="32" fill="hsl(330.00,100.00%,53.33%)" />
<rect x="96" y="0" width="32" height="32" fill="hsl(180.00,100.00%,3.33%)" /> <rect x="96" y="0" width="32" height="32" fill="hsl(330.00,100.00%,70.00%)" />
<rect x="128" y="0" width="32" height="32" fill="hsl(180.00,100.00%,3.33%)" /> <rect x="128" y="0" width="32" height="32" fill="hsl(330.00,100.00%,90.00%)" />
<rect x="160" y="0" width="32" height="32" fill="hsl(180.00,100.00%,23.33%)" /> <rect x="160" y="0" width="32" height="32" fill="hsl(330.00,100.00%,56.67%)" />
<rect x="192" y="0" width="32" height="32" fill="hsl(180.00,100.00%,0.00%)" /> <rect x="192" y="0" width="32" height="32" fill="hsl(330.00,100.00%,63.33%)" />
<rect x="224" y="0" width="32" height="32" fill="hsl(180.00,100.00%,46.67%)" /> <rect x="224" y="0" width="32" height="32" fill="hsl(330.00,100.00%,83.33%)" />
<rect x="0" y="32" width="32" height="32" fill="hsl(180.00,100.00%,43.33%)" /> <rect x="0" y="32" width="32" height="32" fill="hsl(330.00,100.00%,80.00%)" />
<rect x="32" y="32" width="32" height="32" fill="hsl(180.00,100.00%,13.33%)" /> <rect x="32" y="32" width="32" height="32" fill="hsl(330.00,100.00%,90.00%)" />
<rect x="64" y="32" width="32" height="32" fill="hsl(180.00,100.00%,46.67%)" /> <rect x="64" y="32" width="32" height="32" fill="hsl(330.00,100.00%,83.33%)" />
<rect x="96" y="32" width="32" height="32" fill="hsl(180.00,100.00%,10.00%)" /> <rect x="96" y="32" width="32" height="32" fill="hsl(330.00,100.00%,56.67%)" />
<rect x="128" y="32" width="32" height="32" fill="hsl(180.00,100.00%,40.00%)" /> <rect x="128" y="32" width="32" height="32" fill="hsl(330.00,100.00%,100.00%)" />
<rect x="160" y="32" width="32" height="32" fill="hsl(180.00,100.00%,43.33%)" /> <rect x="160" y="32" width="32" height="32" fill="hsl(330.00,100.00%,50.00%)" />
<rect x="192" y="32" width="32" height="32" fill="hsl(180.00,100.00%,46.67%)" /> <rect x="192" y="32" width="32" height="32" fill="hsl(330.00,100.00%,66.67%)" />
<rect x="224" y="32" width="32" height="32" fill="hsl(180.00,100.00%,10.00%)" /> <rect x="224" y="32" width="32" height="32" fill="hsl(330.00,100.00%,100.00%)" />
<rect x="0" y="64" width="32" height="32" fill="hsl(180.00,100.00%,36.67%)" /> <rect x="0" y="64" width="32" height="32" fill="hsl(330.00,100.00%,63.33%)" />
<rect x="32" y="64" width="32" height="32" fill="hsl(180.00,100.00%,6.67%)" /> <rect x="32" y="64" width="32" height="32" fill="hsl(330.00,100.00%,86.67%)" />
<rect x="64" y="64" width="32" height="32" fill="hsl(180.00,100.00%,40.00%)" /> <rect x="64" y="64" width="32" height="32" fill="hsl(330.00,100.00%,96.67%)" />
<rect x="96" y="64" width="32" height="32" fill="hsl(180.00,100.00%,30.00%)" /> <rect x="96" y="64" width="32" height="32" fill="hsl(330.00,100.00%,100.00%)" />
<rect x="128" y="64" width="32" height="32" fill="hsl(180.00,100.00%,26.67%)" /> <rect x="128" y="64" width="32" height="32" fill="hsl(330.00,100.00%,83.33%)" />
<rect x="160" y="64" width="32" height="32" fill="hsl(180.00,100.00%,10.00%)" /> <rect x="160" y="64" width="32" height="32" fill="hsl(330.00,100.00%,86.67%)" />
<rect x="192" y="64" width="32" height="32" fill="hsl(180.00,100.00%,36.67%)" /> <rect x="192" y="64" width="32" height="32" fill="hsl(330.00,100.00%,83.33%)" />
<rect x="224" y="64" width="32" height="32" fill="hsl(180.00,100.00%,6.67%)" /> <rect x="224" y="64" width="32" height="32" fill="hsl(330.00,100.00%,96.67%)" />
<rect x="0" y="96" width="32" height="32" fill="hsl(180.00,100.00%,46.67%)" /> <rect x="0" y="96" width="32" height="32" fill="hsl(330.00,100.00%,63.33%)" />
<rect x="32" y="96" width="32" height="32" fill="hsl(180.00,100.00%,13.33%)" /> <rect x="32" y="96" width="32" height="32" fill="hsl(330.00,100.00%,76.67%)" />
<rect x="64" y="96" width="32" height="32" fill="hsl(180.00,100.00%,20.00%)" /> <rect x="64" y="96" width="32" height="32" fill="hsl(330.00,100.00%,100.00%)" />
<rect x="96" y="96" width="32" height="32" fill="hsl(180.00,100.00%,26.67%)" /> <rect x="96" y="96" width="32" height="32" fill="hsl(330.00,100.00%,66.67%)" />
<rect x="128" y="96" width="32" height="32" fill="hsl(180.00,100.00%,26.67%)" /> <rect x="128" y="96" width="32" height="32" fill="hsl(330.00,100.00%,83.33%)" />
<rect x="160" y="96" width="32" height="32" fill="hsl(180.00,100.00%,3.33%)" /> <rect x="160" y="96" width="32" height="32" fill="hsl(330.00,100.00%,96.67%)" />
<rect x="192" y="96" width="32" height="32" fill="hsl(180.00,100.00%,0.00%)" /> <rect x="192" y="96" width="32" height="32" fill="hsl(330.00,100.00%,83.33%)" />
<rect x="224" y="96" width="32" height="32" fill="hsl(180.00,100.00%,20.00%)" /> <rect x="224" y="96" width="32" height="32" fill="hsl(330.00,100.00%,53.33%)" />
<rect x="0" y="128" width="32" height="32" fill="hsl(180.00,100.00%,43.33%)" /> <rect x="0" y="128" width="32" height="32" fill="hsl(330.00,100.00%,60.00%)" />
<rect x="32" y="128" width="32" height="32" fill="hsl(180.00,100.00%,6.67%)" /> <rect x="32" y="128" width="32" height="32" fill="hsl(330.00,100.00%,66.67%)" />
<rect x="64" y="128" width="32" height="32" fill="hsl(180.00,100.00%,26.67%)" /> <rect x="64" y="128" width="32" height="32" fill="hsl(330.00,100.00%,53.33%)" />
<rect x="96" y="128" width="32" height="32" fill="hsl(180.00,100.00%,30.00%)" /> <rect x="96" y="128" width="32" height="32" fill="hsl(330.00,100.00%,66.67%)" />
<rect x="128" y="128" width="32" height="32" fill="hsl(180.00,100.00%,33.33%)" /> <rect x="128" y="128" width="32" height="32" fill="hsl(330.00,100.00%,96.67%)" />
<rect x="160" y="128" width="32" height="32" fill="hsl(180.00,100.00%,3.33%)" /> <rect x="160" y="128" width="32" height="32" fill="hsl(330.00,100.00%,93.33%)" />
<rect x="192" y="128" width="32" height="32" fill="hsl(180.00,100.00%,36.67%)" /> <rect x="192" y="128" width="32" height="32" fill="hsl(330.00,100.00%,83.33%)" />
<rect x="224" y="128" width="32" height="32" fill="hsl(180.00,100.00%,10.00%)" /> <rect x="224" y="128" width="32" height="32" fill="hsl(330.00,100.00%,53.33%)" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB