Een 88x31-boekknop maken met ImageMagick

Introductie

Als je een aanzienlijke hoeveelheid tijd hebt besteed aan het surfen op het internet (en vooral op het 'Small Web'), heb je waarschijnlijk een 88x31-knop gezien, of zelfs tientallen ervan. Sommigen zien er zo uit:

(Afbeelding)

Het mooie aan computerschermen is echter dat ze in staat zijn om snel wisselende beelden te verwerken, waardoor sommige knoppen animaties hebben:

(Afbeelding)

Het is me opgevallen dat ik, ondanks de talloze voorbeelden, er geen heb gezien die erg ver gaan in die richting. Meestal zijn de animaties er alleen om de aandacht te trekken of om verschillende woorden na elkaar weer te geven. Maar waarom niet Moby Dick?

Groottebeperkingen

Ik was verrast te ontdekken dat er geen limiet lijkt te zijn aan het aantal frames in een GIF-bestand, en dat de maximale resolutie $2^{16}$ bij $2^{16}$ is, wat neerkomt op 4295 megapixels. Wij beperken ons uiteraard tot slechts 88 bij 31 pixels (of 0,003 megapixel), wat betekent dat reguliere lettertypen niet veel ruimte hebben om te schitteren. Arial wordt bijvoorbeeld pas leesbaar bij een minimale hoogte van 10 pixels, waardoor we ongeveer elf woorden tegelijk kunnen weergeven.

Alternatieve lettertypen

Zoals vaak gebeurt in de informatica, zorgen populaire conventies er uiteindelijk voor dat iemand gefrustreerd raakt en een alternatieve methode ontwikkelt. In dit geval zoeken we naar lettertypen die zijn ontworpen om leesbaar te zijn bij extreem kleine lettergroottes. Er zijn lettertypen die slechts 3x3 pixels groot zijn, maar persoonlijk vind ik TomThumb de ideale middenweg. Je kunt TomThumb in TrueType-formaat downloaden.

Moby Dick verkrijgen

Allereerst heb je een kopie van de inhoud van het boek in platte tekst nodig. De methoden kunnen variëren afhankelijk van de formaten waar je toegang toe hebt: je kunt OCR gebruiken om de tekst uit een fysiek boek te halen, bij een .EPUB of .PDF kun je deze converteren (of de tekst handmatig kopiëren), of je hebt geluk en vindt het boek al als een .txt-bestand, wat het geval is bij Moby Dick.

Ik heb het bestand gedownload en de licentietekst aan het begin en het einde verwijderd. Ook heb ik alles vóór het eerste hoofdstuk weggeknipt.

Het werk formatteren

Als we kijken naar onze knop (88x31) en ons lettertype (6x4, inclusief spaties), zien we dat we 5 rijen van elk 22 tekens kunnen plaatsen. ImageMagick, de tool die we gaan gebruiken, is niet erg goed in het lay-outen van tekst, dus het is verstandig om dat zelf te doen. Er zijn verschillende manieren om dit aan te pakken, maar de netste methode maakt gebruik van drie POSIX-tools: cat, tr en fold:

cat input.txt | tr '\n' ' ' | tr -d '\r' | fold -s -w 22 > 22w.txt
  • cat wordt gebruikt om de tekst naar tr te sturen.
  • tr vertaalt elke nieuwe regel naar een spatie, waardoor het hele tekstbestand tot één regel wordt samengevoegd.
  • fold neemt die ene regel en splitst deze in meerdere regels van maximaal 22 tekens breed (-w 22), waarbij geprobeerd wordt om woorden niet in het midden door te splitsen (-s).

Het is waarschijnlijk dat je tekst op dit punt prima oogt. De mijne was een beetje vervormd, omdat fold niet goed omgaat met multibyte-tekens. Ik heb gecontroleerd welke non-ASCII-tekens input.txt bevatte en deze verwijderd met sed, als volgt:

sed -i 's/”/"/g'

De -i vlag stelt je in staat om het bestand ter plekke te wijzigen. Je kunt alle non-ASCII-tekens vinden met grep:

grep -P -n '[^\x00-\x7F]' input.txt

Uiteraard is formattering subjectief. Afhankelijk van het soort literair werk wil je dit misschien anders doen. Ik heb sed -i 's/CHAPTER /\n\n\nCHAPTER /g' input.txt gebruikt om wat ruimte tussen de hoofdstukken toe te voegen, maar hoofdstukken kunnen in de tekst die jij gebruikt anders gemarkeerd zijn, of ze kunnen helemaal niet aanwezig zijn.

En hoe maak je er een GIF van?

Voor dit deel moet je ImageMagick geïnstalleerd hebben. Waarschijnlijk heb je dit al. We gebruiken het volgende commando om de eerste versie van ons GIF-bestand te genereren:

cat 22w.txt | convert -page 88x39+0+0 -background white -fill black -font tom.ttf -pointsize 6 text:- high.gif

Let op dat ik het tom.ttf-bestand in de huidige werkmap heb geplaatst. Het commando is grotendeels zelfverklarend: convert neemt de tekst uit de standaardinvoer en plaatst deze frame voor frame in een GIF.

Er lijkt echter een marge aan de onderkant van de afbeelding te worden geforceerd, wat de reden is dat we de tekst op een afbeelding hebben gezet die acht pixels hoger is dan we wilden. We gaan dit nu bijsnijden:

convert high.gif -set delay 600 -coalesce -repage 0x0 -crop 88x31+0+0 +repage good.gif

We snijden die laatste acht pixels eraf en stellen een redelijke vertraging (delay) tussen de frames in (naar mijn ervaring is 6 seconden prima — laat me weten of je het hier niet mee eens bent).

Nu zou good.gif er ongeveer zo uit moeten zien:

(Afbeelding)

Python-bonus: gecentreerde tekst

Ik dacht dat het mooi zou zijn om de tekst te centreren, in plaats van dat deze strak tegen de linkerkant aanplakt. Ik heb hiervoor een kort Python-script geschreven, dit uitvoerbaar gemaakt, de output naar een bestand gepiped en vervolgens opnieuw de GIF gegenereerd.

#!/usr/bin/python3
from math import floor

with open("22w.txt") as file:
    for line in file:
        i = (22-len(line.strip()))/2
        o = " "*floor(i)+line.strip()
        print(o)

Moby Dick-bonus: het volledige boek

Om bandbreedte te besparen, zijn de bovenstaande GIF's voorbeelden die slechts het eerste hoofdstuk bevatten. Klik hier om de volledige schoonheid van 4,2 MB te aanschouwen, die meer dan 19 uur duurt.