59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Convert the generated Hydra silhouette to Fastfetch ASCII using Pillow.
|
|
|
|
Run from the repository root with Python + Pillow (development only):
|
|
python3 dev/render-logo.py
|
|
"""
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
from PIL import Image
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
RAMP = ' .:-=+*#%@' # '$' is reserved for Fastfetch color placeholders.
|
|
CAPTION = 'H Y D R A O S'
|
|
|
|
|
|
def render(source, columns):
|
|
# This is a single-color mark: opacity, not luminance, defines its shape.
|
|
# Threshold near-transparent generation noise before reducing the image.
|
|
with Image.open(source) as image:
|
|
mask = image.convert('RGBA').getchannel('A').point(
|
|
lambda value: 255 if value > 160 else 0)
|
|
bounds = mask.getbbox()
|
|
if bounds is None:
|
|
raise ValueError('The source image has no visible silhouette')
|
|
mask = mask.crop(bounds)
|
|
# A terminal character is approximately twice as tall as it is wide.
|
|
rows = max(1, round(mask.height / mask.width * columns * 0.5))
|
|
pixels = mask.resize((columns, rows), Image.Resampling.LANCZOS)
|
|
lines = []
|
|
for y in range(rows):
|
|
line = ''
|
|
for x in range(columns):
|
|
coverage = pixels.getpixel((x, y)) / 255
|
|
level = min(9, max(0, round((coverage - 0.09) / 0.82 * 9)))
|
|
line += RAMP[level]
|
|
lines.append(line.rstrip())
|
|
return '$1' + '\n'.join(lines) + '\n\n$2' + CAPTION.center(columns).rstrip() + '\n'
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('--source', type=Path,
|
|
default=ROOT / 'assets/branding/hydra-mark.png')
|
|
parser.add_argument('--output', type=Path,
|
|
default=ROOT / 'image/rootfs/usr/share/hydra/fastfetch.txt')
|
|
parser.add_argument('--columns', type=int, default=44)
|
|
args = parser.parse_args()
|
|
if not len(CAPTION) <= args.columns <= 100:
|
|
parser.error('columns must be between 13 and 100')
|
|
args.output.write_text(render(args.source, args.columns), encoding='ascii')
|
|
print(args.output)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|