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 .colorizer import PaletteColorizer
|
||||||
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 .svg import gensvg
|
from .writer import ANSIWriter, SVGWriter
|
||||||
|
|
||||||
|
|
||||||
# TODO - WASM compile for embedding directly in HTML
|
# TODO - WASM compile for embedding directly in HTML
|
||||||
# TODO - option to add a caption based on the filename
|
# TODO - option to add a caption based on the filename
|
||||||
# TODO - load palettes from a file
|
# TODO - load palettes from a file
|
||||||
# TODO - ANSI 24-bit color output
|
|
||||||
|
|
||||||
def cli_main() -> None:
|
def cli_main() -> None:
|
||||||
"Main function entrypoint."
|
"Main function entrypoint."
|
||||||
@@ -49,7 +49,14 @@ def cli_main() -> None:
|
|||||||
INPUT_TYPE_HELP = "INPUT TYPE (-x, --input-type)\n" + "\n".join(
|
INPUT_TYPE_HELP = "INPUT TYPE (-x, --input-type)\n" + "\n".join(
|
||||||
[f" {choice} - {desc}" for choice, desc in INPUT_TYPE_CHOICES.items()]
|
[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]
|
progname: str = sys.argv[0]
|
||||||
if progname.endswith("__main__.py"):
|
if progname.endswith("__main__.py"):
|
||||||
@@ -102,12 +109,11 @@ def cli_main() -> None:
|
|||||||
help="Choose the hash algorithm. default: sha512",
|
help="Choose the hash algorithm. default: sha512",
|
||||||
)
|
)
|
||||||
ap.add_argument(
|
ap.add_argument(
|
||||||
"-z",
|
"--svg-square-size",
|
||||||
"--square-size",
|
|
||||||
metavar="PX",
|
metavar="PX",
|
||||||
type=int,
|
type=int,
|
||||||
default=32,
|
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(
|
ap.add_argument(
|
||||||
"-x",
|
"-x",
|
||||||
@@ -116,6 +122,13 @@ def cli_main() -> None:
|
|||||||
choices=INPUT_TYPE_CHOICES.keys(),
|
choices=INPUT_TYPE_CHOICES.keys(),
|
||||||
help="Determines how the input should be treated. default: path",
|
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()
|
args = ap.parse_args()
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
@@ -182,9 +195,19 @@ def cli_main() -> None:
|
|||||||
# Print SVG
|
# Print SVG
|
||||||
matrix = matricizer.matricize(hashdata)
|
matrix = matricizer.matricize(hashdata)
|
||||||
colors = colorizer.colorize(matrix)
|
colors = colorizer.colorize(matrix)
|
||||||
svg = gensvg(colors, args.square_size)
|
|
||||||
if str(args.out) == "-":
|
# Choose the output writer
|
||||||
sys.stdout.write(svg)
|
writer: Writer
|
||||||
else:
|
match args.output_type:
|
||||||
args.out.write_text(svg)
|
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
|
while read infile; do
|
||||||
for hash in "${hashes[@]}"; do
|
for hash in "${hashes[@]}"; do
|
||||||
for matrix in "${matrices[@]}"; do
|
for matrix in "${matrices[@]}"; do
|
||||||
outfile="examples/$(basename -s .in "$infile")-$hash-$matrix.svg"
|
svgfile="examples/$(basename -s .in "$infile")-$hash-$matrix.svg"
|
||||||
echo "Generating $outfile"
|
pngfile="examples/$(basename -s .in "$infile")-$hash-$matrix.png"
|
||||||
python3 -m colorhash "$infile" --out "$outfile" --hash "$hash" --matrix "$matrix"
|
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
|
done
|
||||||
done
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user