Mai 08
Codekomprimierung mal anders
Jacob Seidelin hatte am vergangenen Wochenende scheinbar seinen Spaß und bastelte an einer weiteren verrückten Idee: Javascriptcode in Bilddateien ablegen. Dabei erreichte er beachtliche Ergebnisse. Die 124 Kilobyte große Prototype-Bibliothek packte er in eine 30 Kilobyte kleine 8-bit-png-Grafik.
Seidelin, der bereits durch seine durch seine Spieleumsetzungen von Super Mario und Wolfenstein 3D auf sich aufmerksam machte, beteuert, dass es bei seiner Demonstration nur um eine Machbarkeitsstudie handelt, die dem im Web häufig anzutreffenden gzip-Komprimieralgorithmus nicht den Rang ablaufen kann.
Zu Beginn seines Vorhabens Code in Grafiken abzuspeichern, stellte sich Seidelin die Frage nach dem zu verwendenten Dateiformat. Sämtliche verlustbehafteten Formate waren von Anfang ausgeschlossen. Somit blieben nur GIF und PNG übrig. PNG bietet indes 2 verschiedene Modi: 24 bit und 8 bit. Durch einfaches Probieren mit Photoshop kam Seidelin zu dem Ergebnis, dass die 8-bit-PNG-Variante die beste Wahl in Sachen Komprimierung ist.
Das Umwandeln der Javascript-Bibliothek Prototype in Farbwerte, die in der PNG-Grafik hinterlegt werden, geschieht in einem PHP-Script. Die PHP-Datei dient dazu die JS-Datei einzulesen, die PNG-Grafik zu erzeugen und jedem Pixel einen Wert zwischen 0 und 255 entsprechend des ASCII-Wertes eines jeden Zeichens der JS-Datei zuzuweisen.
Als Ergebnis erhält man eine PNG-Grafik, die Prototype exakt aber komprimiert abbildet.
Mit Hilfe des Canvas-Elements kann die Grafik einfach über die Funktion drawImage() gezeichnet und über getImageDate() pixelweise eingelesen werden. Auf diese Weise erhält man ein Array aus Werten, wobei jedes Pixel aus 4 Farbwerten (RGBA) besteht. Da unsere Grafik aber nur einen 8-bit-Farbraum darstellt, wird nur jeden vierten Wert benötigt. Reiht man nun all diese Werte auf und verwendet die eval()-Funktion von Javascript erhält man seine ursprünge Protoytpe-Datei zurück.
Die komplette Dekomprimierfunktion sieht man hier.
Da das hier vorgestellte Verfahren die Unterstützung des HTML5-Elementes Canvas voraussetzt, funktioniert es auch nur in den aktuellen Versionen der Browser Firefox, Opera und WebKit. Der Internet Explorer muss wegen fehlender Canvas-Unterstützung außen vor bleiben.
Wer neugierig geworden ist, kann auf dieser Demoseite verschiedene Testdateien komprimieren und sich anzeigen lassen.