Add ANSI color output, set that as the default
ANSI-based color output is available and now the default. Add a -y / --output-type argument to select SVG or ANSI output. Also update tools/genexamples.sh to use the SVG output type. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -8,13 +8,13 @@ import textwrap
|
||||
from .colorizer import PaletteColorizer
|
||||
from .matricizer import Matricizer, NibbleMatricizer, RandomartMatricizer
|
||||
from .palettes import Palette, DEFAULT_PALETTES, PALETTES
|
||||
from .svg import gensvg
|
||||
from .writer import ANSIWriter, SVGWriter
|
||||
|
||||
|
||||
# TODO - WASM compile for embedding directly in HTML
|
||||
# TODO - option to add a caption based on the filename
|
||||
# TODO - load palettes from a file
|
||||
# TODO - ANSI 24-bit color output
|
||||
|
||||
|
||||
def cli_main() -> None:
|
||||
"Main function entrypoint."
|
||||
@@ -49,7 +49,14 @@ def cli_main() -> None:
|
||||
INPUT_TYPE_HELP = "INPUT TYPE (-x, --input-type)\n" + "\n".join(
|
||||
[f" {choice} - {desc}" for choice, desc in INPUT_TYPE_CHOICES.items()]
|
||||
)
|
||||
EPILOGUE = "\n\n".join([MATRIX_HELP, PALETTE_HELP, INPUT_TYPE_HELP])
|
||||
OUTPUT_TYPE_CHOICES = {
|
||||
"ansi": "the output should be colored for ANSI terminals using 24 bit true color",
|
||||
"svg": "the output should be an SVG format",
|
||||
}
|
||||
OUTPUT_TYPE_HELP = "OUTPUT TYPE (-y, --output-type)\n" + "\n".join(
|
||||
[f" {choice} - {desc}" for choice, desc in OUTPUT_TYPE_CHOICES.items()]
|
||||
)
|
||||
EPILOGUE = "\n\n".join([MATRIX_HELP, PALETTE_HELP, INPUT_TYPE_HELP, OUTPUT_TYPE_HELP])
|
||||
|
||||
progname: str = sys.argv[0]
|
||||
if progname.endswith("__main__.py"):
|
||||
@@ -102,12 +109,11 @@ def cli_main() -> None:
|
||||
help="Choose the hash algorithm. default: sha512",
|
||||
)
|
||||
ap.add_argument(
|
||||
"-z",
|
||||
"--square-size",
|
||||
"--svg-square-size",
|
||||
metavar="PX",
|
||||
type=int,
|
||||
default=32,
|
||||
help="Decide how big the output squares are, in pixels. default: 32",
|
||||
help="For SVG outputs, decide how big the output squares are, in pixels. default: 32",
|
||||
)
|
||||
ap.add_argument(
|
||||
"-x",
|
||||
@@ -116,6 +122,13 @@ def cli_main() -> None:
|
||||
choices=INPUT_TYPE_CHOICES.keys(),
|
||||
help="Determines how the input should be treated. default: path",
|
||||
)
|
||||
ap.add_argument(
|
||||
"-y",
|
||||
"--output-type",
|
||||
default="ansi",
|
||||
choices=OUTPUT_TYPE_CHOICES.keys(),
|
||||
help="Determines how the output should be generated. default: ansi",
|
||||
)
|
||||
args = ap.parse_args()
|
||||
|
||||
############################################################################
|
||||
@@ -182,9 +195,19 @@ def cli_main() -> None:
|
||||
# Print SVG
|
||||
matrix = matricizer.matricize(hashdata)
|
||||
colors = colorizer.colorize(matrix)
|
||||
svg = gensvg(colors, args.square_size)
|
||||
if str(args.out) == "-":
|
||||
sys.stdout.write(svg)
|
||||
else:
|
||||
args.out.write_text(svg)
|
||||
|
||||
# Choose the output writer
|
||||
writer: Writer
|
||||
match args.output_type:
|
||||
case "ansi":
|
||||
writer = ANSIWriter()
|
||||
case "svg":
|
||||
writer = SVGWriter(args.svg_square_size)
|
||||
|
||||
output = writer.write(colors)
|
||||
|
||||
if str(args.out) == "-":
|
||||
sys.stdout.write(output)
|
||||
else:
|
||||
args.out.write_text(output)
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
"SVG-related functions."
|
||||
from .colorizer import ColorMatrix
|
||||
|
||||
|
||||
def gensvg(matrix: ColorMatrix, square_size: int) -> str:
|
||||
"""
|
||||
Generate an SVG based on a given matrix.
|
||||
|
||||
:param matrix: the color matrix to generate the SVG for.
|
||||
:param square_size: the size of the squares generated, in pixels.
|
||||
:returns: the full generated SVG as a string.
|
||||
"""
|
||||
h = len(matrix)
|
||||
w = len(matrix[0])
|
||||
|
||||
# Start SVG string
|
||||
svg = f'<svg width="{w * square_size}" height="{h * square_size}" xmlns="http://www.w3.org/2000/svg">\n'
|
||||
|
||||
# Generate grid
|
||||
for r in range(h):
|
||||
for c in range(w):
|
||||
x = c * square_size
|
||||
y = r * square_size
|
||||
color = matrix[r][c]
|
||||
svg += f' <rect x="{x}" y="{y}" width="{square_size}" height="{square_size}" fill="{color.to_html_color()}" />\n'
|
||||
|
||||
# Close SVG string
|
||||
svg += "</svg>"
|
||||
return svg
|
||||
71
colorhash/writer.py
Normal file
71
colorhash/writer.py
Normal file
@@ -0,0 +1,71 @@
|
||||
import abc
|
||||
|
||||
from .color import Color
|
||||
from .colorizer import ColorMatrix
|
||||
|
||||
|
||||
class Writer(metaclass=abc.ABCMeta):
|
||||
"""
|
||||
Base writer class.
|
||||
|
||||
This is used to write an input colorized matrix to a string, which is then forwarded to the
|
||||
appropriate output.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def write(self, matrix: ColorMatrix) -> str:
|
||||
"Write the color matrix to a string."
|
||||
|
||||
|
||||
class ANSIWriter(Writer):
|
||||
def write(self, matrix: ColorMatrix) -> str:
|
||||
ESC = '\x1b'
|
||||
RESET = f"{ESC}[0m"
|
||||
C = "██"
|
||||
def ansi_color(c: Color) -> str:
|
||||
c = c.to_rgb()
|
||||
return f"{ESC}[38;2;{round(c.r)};{round(c.g)};{round(c.b)}m"
|
||||
out = ''
|
||||
for row in matrix:
|
||||
for col in row:
|
||||
out += ansi_color(col)
|
||||
out += C
|
||||
out += "\n"
|
||||
out += RESET
|
||||
return out
|
||||
|
||||
|
||||
class SVGWriter(Writer):
|
||||
def __init__(self, square_size: int) -> None:
|
||||
"""
|
||||
Create a new SVG writer that uses the given square size.
|
||||
|
||||
:param square_size: the size of the squares generated, in pixels.
|
||||
"""
|
||||
self.square_size = square_size
|
||||
|
||||
def write(self, matrix: ColorMatrix) -> str:
|
||||
"""
|
||||
Generate an SVG based on a given matrix.
|
||||
|
||||
:param matrix: the color matrix to generate the SVG for.
|
||||
:returns: the full generated SVG as a string.
|
||||
"""
|
||||
h = len(matrix)
|
||||
w = len(matrix[0])
|
||||
|
||||
# Start SVG string
|
||||
svg = f'<svg width="{w * self.square_size}" height="{h * self.square_size}" xmlns="http://www.w3.org/2000/svg">\n'
|
||||
|
||||
# Generate grid
|
||||
for r in range(h):
|
||||
for c in range(w):
|
||||
x = c * self.square_size
|
||||
y = r * self.square_size
|
||||
color = matrix[r][c]
|
||||
svg += f' <rect x="{x}" y="{y}" width="{self.square_size}" height="{self.square_size}" fill="{color.to_html_color()}" />\n'
|
||||
|
||||
# Close SVG string
|
||||
svg += "</svg>"
|
||||
return svg
|
||||
|
||||
@@ -11,9 +11,12 @@ find "examples" -type f -name '*.in' | \
|
||||
while read infile; do
|
||||
for hash in "${hashes[@]}"; do
|
||||
for matrix in "${matrices[@]}"; do
|
||||
outfile="examples/$(basename -s .in "$infile")-$hash-$matrix.svg"
|
||||
echo "Generating $outfile"
|
||||
python3 -m colorhash "$infile" --out "$outfile" --hash "$hash" --matrix "$matrix"
|
||||
svgfile="examples/$(basename -s .in "$infile")-$hash-$matrix.svg"
|
||||
pngfile="examples/$(basename -s .in "$infile")-$hash-$matrix.png"
|
||||
echo "Generating $svgfile"
|
||||
python3 -m colorhash "$infile" --output-type svg --out "$svgfile" --hash "$hash" --matrix "$matrix"
|
||||
echo "Generating $pngfile"
|
||||
convert "$svgfile" "$pngfile"
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user