#!/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()