Install PILLOW:
pip install pillow
Execute script:
./draw-fonts-samples --fonts-dir ~/tmp/Fonts --output-dir thumbnails
After script execution you may want to compress resulting PNG files using optipng.
#!/usr/bin/env python3 | |
""" | |
Create samples of each truetype font from the specified directory as | |
a single html page with png images representing glyphs from each font. | |
Original source: https://gist.github.com/sigsergv/9309ad0e3b3c2be65aa58c37d259f580 | |
Author: Sergey Stolyarov <[email protected]> | |
License: Public Domain | |
Requirements: PILLOW | |
""" | |
import argparse | |
import os | |
from sys import exit | |
from PIL import Image, ImageDraw, ImageFont | |
from datetime import datetime | |
p = argparse.ArgumentParser() | |
p.add_argument('--fonts-dir', dest='fonts_dir', required=True, help='Path to directory with truetype fonts.') | |
p.add_argument('--output-dir', dest='output_dir', required=True, | |
help='Path to output directory where index.html and a set of .png images to be created.') | |
args = p.parse_args() | |
SAMPLE_STRING = '''0123456789!@#$%^&*(){}[] | |
THE FIVE BOXING WIZARDS JUMP QUICKLY. | |
the five boxing wizards jump quickly. | |
ЮЖНО-ЭФИОПСКИЙ ГРАЧ УВЁЛ МЫШЬ ЗА ХОБОТ НА СЪЕЗД ЯЩЕРИЦ. | |
южно-эфиопский грач увёл мышь за хобот на съезд ящериц. | |
''' | |
fonts_dir = args.fonts_dir | |
out_dir = args.output_dir | |
if not os.path.isdir(fonts_dir): | |
print(f'Fonts directory `{fonts_dir}` not found!') | |
exit(1) | |
if not os.path.isdir(out_dir): | |
print(f'Output directory `{out_dir}` not found!') | |
exit(1) | |
text_color = (0, 0, 0) | |
bg_color = (255, 255, 255) | |
font_size = 48 | |
html = '''<html> | |
<head> | |
<title>Fonts samples</title> | |
<style> | |
body { | |
background-color: white; | |
color: black; | |
font-family: sans-serif; | |
} | |
h3 { | |
border-style: none none solid none; | |
border-color: black; | |
border-width: 3px; | |
} | |
</style> | |
</head> | |
<body> | |
''' | |
html += '<h1>Index of truetype fonts</h1>\n' | |
html += f'<div>TrueType directory: {fonts_dir}</div>\n' | |
today = datetime.today().isoformat() | |
html += f'<div>Generated on: {today}</div>\n' | |
fonts_html_block = '' | |
ttf_num = 0 | |
for ind, font_file in enumerate(os.listdir(fonts_dir)): | |
font_file = os.path.join(fonts_dir, font_file) | |
if not os.path.isfile(font_file): | |
# skipping non-files | |
continue | |
try: | |
font = ImageFont.truetype(font_file, font_size) | |
except: | |
print(f'`{font_file}` is not a valid truetype font! skipping') | |
continue | |
font_name, font_style = font.getname() | |
fonts_html_block += f'<h3>{font_name} {font_style}</h3>\n' | |
# calculate text box | |
dummy_image = Image.new('RGB', (1, 1)) | |
dummy_draw = ImageDraw.Draw(dummy_image) | |
bbox = dummy_draw.textbbox((0, 0), SAMPLE_STRING, font=font) | |
width = bbox[2] - bbox[0] | |
height = bbox[3] - bbox[1] | |
# create target image | |
image_file = f'img_{ind}.png' | |
image_path = os.path.join(out_dir, image_file) | |
image = Image.new('RGB', (width + 20, height + 20), color=bg_color) | |
draw = ImageDraw.Draw(image) | |
draw.text((0, 0), SAMPLE_STRING, font=font, fill=text_color) | |
image.save(image_path, 'png') | |
# append to html | |
fonts_html_block += f'<div><img src="{image_file}"></div>\n' | |
ttf_num += 1 | |
html += f'<div>Total files: {ttf_num}</div>\n' | |
html += fonts_html_block | |
html += '</body></html>' | |
index_html = os.path.join(out_dir, 'index.html') | |
with open(index_html, 'w') as ifp: | |
ifp.write(html) |