Typo3 und ImageMagick – was zu beachten ist

Für einen guten Zweck arbeite ich auch als Hosting-Anbieter für die Interessensgemeinschaft Herzogenried. Die Verbindung zum Quatiermanagement entstand schon vor einigen Jahren, damals ging es primär darum überhaupt eine Präsenz im Netz aufzubauen. Der verantwortliche Mitarbeiter war mir schon von daher sympathisch, dass er vieles bis ins Detail verstehen wollte und auch im Netz selbstständig agieren wollte. Er hat sich mit enormen Eifer und einiger Unterstützung damals die Grundlagen von HTML selbst beigebracht.

Zwischenzeitlich ist der Bedarf gewachsen, es wurde umgestellt auf Joomla! als Content-Management-System (CMS) – für mich auch keine große Sache, jedoch habe ich mich nicht in der Tiefe mit dem System auseinander setzen können wie ich es gerne gewollt hätte. Aber die Mannschaft hat es auch so recht gut hinbekommen – einige Kleinigkeiten habe ich noch unterstützend beitragen können.

Nunmehr stand wieder ein Neuanfang auf dem Programm – von Zeit zu Zeit sollte jede Homepage mal einem Review und ggf. auch einer Modernisierung unterzogen werden. Wie sich zeigte war Joomla! nicht mehr die absolute Präferenz, zumal sich nun auch Personen mit deutlich besseren Kenntnissen in Sachen Layout und Gestaltung gefunden hatten. Die neue Homepage soll unter Typo3 entstehen. Mir ist das System letztlich egal – jeder soll das System verwenden mit dem er am Besten arbeiten kann. Nicht jedes Werkzeug ist automatisch für jeden Zweck geeignet nur weil viele es für diesen einsetzen.

Für mich als Systemadmin ändert sich durch den Wechsel des CMS eigentlich nichts – die Anforderungen sind recht human: Apache als Webserver (es gingen wohl auch einige andere), MySQL bzw. MariaDB als Datenbank und PHP als Skriptsprache die das ganze zusammen hält. Soweit nichts außergewöhnliches.

Schon interessanter werden da diverse nette Features die Typo3 so mitbringt, wie etwa das automatische Skalieren von Bildern oder auch die Erzeugung von PDFs. Alles Funktionen die gut ankommen wenn man sie richtig einsetzt. Für die ganze Bildbearbeitung kommt ein mir nicht unbekanntes Tool zum Einsatz ImageMagick – diese in C geschriebene Toolbox ist das Schweizer Taschenmesser was automatisierte Bildbearbeitung betrifft – die Bedienung der Tools auf der Kommandozeile scheint anfänglich etwas kryptisch, aber gerade für Stapelaufgaben ist sie hervorragend geeignet. Die Libary dazu habe ich schon länger auf meinem Server installiert – für meine Webprojekte verwende ich direkt die PHP-Schnittstelle, die auf den Namen Imagick hört. Diese ermöglicht unter anderem die Berechnung von Thumbnails on demand, und ist dabei dank C-Implementierung um ein vielfaches schneller als die GDLib, die sonst in PHP für die Bearbeitung von Bildern verwendet wird. Ich selbst habe Imagick schon für die von mir betreute Website der THW-Jugend in Mannheim verwendet – irgendwann war es mir einfach lästig geworden jedes Mal für eine Bildergalerie die Thumbnails von Hand zu berechnen – mit ein klein wenig Datenbank-Background habe ich das dann aus der Welt geschafft. Klingt zwar im ersten Moment etwas schräg ausgerechnet Bilder als Binary large Object in eine Datenbank zu packen, aber die Optionen sind einfach zu schön. Mal ganz davon abgesehen, dass man sich nicht mehr um irgendwelche Dateirechte in shared hosting Umgebungen Gedanken machen muss – auch etwas wie Schlagworte oder Gruppierungen sind in einer relationalen Datenbank einfach wesentlich leichter möglich, als wenn alles im Dateisystem liegt.

Typo3 geht einen etwas anderen, universelleren Weg und ruft das Tool „convert“ aus dem Imagick-Paket auf – das macht es mächtiger aber in meinen Augen auch umständlicher zu bedienen. Jedenfalls ist die Installation auch kein Hexenwerk. Paketverwaltung auf – installieren, ja, Installation fertig. Soweit mal die Vorbereitung.

Die Rückmeldung lässt nicht lange auf sich warten: ImageMagick funktioniert generell, aber wir haben ein Problem mit der Version … der Kunde wünscht in diesem Fall eine ältere Version – was mir als Betreiber natürlich etwas widerstrebt, gibt es doch zahlreiche Bugfixes auf die ich selbst angewiesen bin und diverse kleinere Lücken im Code, die geschlossen wurden.

Nach etlichem Hin und Her ist das Problem zumindest einmal eingegrenzt: Wann immer man mit Typo3 versucht eine Adobe Illustrator-Datei in ein JPEG zu überführen, knirscht es bezüglich der verwendeten Transparenz. Der Hintergrund wird nicht weiß sondern schwarz dargestellt, was gerade beim Weiterverwenden in PDFs nicht gut aussieht.

In diversen Foren ist das Problem auch beschrieben und es gibt diverse Abhilfe Vorschläge – unter anderem ein Downgrade, was für mich ja wie geschrieben eigentlich nicht in Frage kommt. Also geht die Suche nach der Ursache weiter – ich bin ja sogar Willens mich ggf. mit dem Code von Image Magick auseinander zu setzen – Bildbearbeitungsalgorithmen habe ich zwar mal gelernt, aber so schwer kann es in dem Fall ja nicht werden.

Über mehrere Zwischenstufen kristallisiert sich für mich langsam die Struktur von ImageMagick heraus – mit Nichten ist das eine allwissende Bibliothek mit angeschlossenem Werkzeugkasten, wie ich lange Zeit gedacht hatte. Vielmehr lagert ImageMagick diverse Aufgaben an dezidierte Programme aus – was ja auch sinnvoll ist, man braucht das Rad ja nicht zweimal zu erfinden und nirgendwo ist die Wiederverwendung von Programmen und Code so einfach wie in Software und gerade im OpenSource-Bereich.

Ich lerne Adobe Illustrator Dateien sind nur verkappte PDFs mit einigen Erweiterungen – zum Lesen eignet sich das vielseitige Ghostscript, das ursprünglich mal als PostScript-Interpreter gestartet ist. Man muss wissen, dass PDF anfänglich auch nur eine etwas aufgebohrte Version von PostScript war. PostScript war lange Zeit die Sprache um Drucker sauber und effizient anzusteuern – ein guter Netzwerkdrucker versteht sich zur Freude von Linux-Anwendern und Mac-Nutzern auch heute noch auf PostScript. Die Logik zur Aufbereitung von Dokumenten und Druckvorbereitung lag damals schon im Drucker. Erst mit GDI und PCL gab es die ersten „Thin“-Printer – also Drucker ohne große Eigenintelligenz die vom Rechner „ferngesteuert“ wurden. PDF war der Schritt vom Papier in die digitale Welt – also eine Art unabhängiges Dokumentenformat, das sich aber auch auf Referenzen verstand.

Halten wir also fest Typo3 ruft ImageMagick bzw. dessen Tool convert mit einigen Parametern auf, das wiederum übergibt die Sache zumindest teilweise an Ghostscript. Was genau wohin übergeben wird, steht in der

delegates.xml

– wo genau die sich findet hängt ein wenig von der Distribution ab – unter Ubuntu findet man sie unter

/etc/ImageMagick/delegates.xml

.

Einer der Tipps aus den Foren lautet den vollständigen Pfad für ghostscript gs  anzugeben, das betrifft aber im Wesentlichen die Windows-Welt – schaden kann es ja mal nichts, aber leider bleibt mir der Erfolg versagt. Das Problem besteht weiterhin – die Hintergründe werden schwarz anstelle transparent (also weiß) dem auf Papier (es sei denn man druckt gerne auf schwarz, wobei dann die meisten Drucker mit ihren Farben an die Grenzen des Möglichen kommen – weiß als Tinte oder Toner habe ich noch bei den wenigsten Druckern gesehen).

Nächster Schritt in der Fehlersuche: Handarbeit: Also einmal ein Bild von Hand auf der Kommandozeile mit convert umwandeln – die Befehlszeile dazu lautet anhand von Typo3:

convert' +profile '*' -geometry 170x170! -colorspace RGB -quality 70  'typo3logotype.ai'[0] 'install_read_ai.jpg'

Was mir auffällt: Das Ausgabe-Format ist JPEG – wie ich weiß und mich auch nochmals informiere unterstützt JPEG keine Transparenz (dafür gibt es andere praktische Formate wie PNG oder früher auf GIF) – indem ich mir ein PNG ausgeben lasse, kann ich das Problem wieder ein Stück herunter brechen: Das Einlesen funktioniert wohl sauber, denn das ausgegebene Bild enthält korrekt weiterhin die Transparenz – ergo muss irgendwas bei der Umwandlung in JPEG schiefgehen.

Die Lösung des Problems ist recht simpel:

-background white -flatten

in die Angabe eingebaut und schon kommt das passende Ergebnis bei heraus – es geht unter anderem natürlich auch mit anderen Farben als Hintergrund.

Nun ist eine Lösung an sich ja schon mal was tolles, aber ich will ja wissen warum es früher mal so funktioniert hat und jetzt nicht mehr. Wie schon vermutet hat sich in der neuen Version von ImageMagick etwas bei JPEG schreiben verändert. Die Funktion zum „plattklopfen“ bzw. dem Zusammenführen von Ebenen aus einen konstruierten Bild wird jetzt nicht mehr implizit aufgerufen. Bei vorherigen Versionen war dies der Fall wenn Transparenz vorlag und ein Hintergrund gegeben wurde. So eine simple und auch gut nachvollziehbare Änderung (jede Funktion sollte das machen was drauf steht, das richtig, aber auch bitte nicht noch mehr), hat mich hier eine ganze Weile auf Trab gehalten.

Wenn man den Aufruf in der Typo3-Konfiguration anpasst, dann klappt auch die Umwandlung ohne Probleme. Nur schade, dass diese so simple Lösung (die noch dazu auch mit älteren Versionen von ImageMagick richtige Ergebnisse liefert) den Weg noch nicht in die aktuelle Fassung von Typo3 gefunden hat. Wollen wir hoffen, das dies bald der Fall ist.

Quick’n’Dirty in MySQL und anderen Datenbanken

Heute habe ich mich mal wieder einer Altlast der Datenbankentwicklung hingegeben, da sich einige Veränderungen ergeben hatten. Ich hatte schon mehrfach, die Hoffnung diese Tabellen der Datenbank endlich einmal längere Zeit in Ruhe lassen zu können um mich neuen Funktionen zu widmen – aber Pustekuchen wars.

Also wieder das Design auf den Prüfstand und schauen wie man es an die neuen Anforderungen anpassen kann. Ich weiß, dass ich vor etwa einem halben Jahr noch mit einem Freund und ausgesprochenen Experten in Sachen Datenbankdesign mich über einige Dinge ausgetauscht habe. An einigen Stellen hatte ich mich für geschickt gehalten bzw. wollte an dem Design nicht mehr übermäßig rütteln. Es hat ja auch alles soweit funktioniert und gerade die Schlüsseldefinitionen folgten auch einer gewissen Logik. Ich hatte mich für einen kombinierten Schlüssel entschieden – ein referenziertes Objekt kann zu einem Zeitpunkt (auf die Sekunde genau) nur an einer Stelle sein – für den Anwendungsfall eine absolut zutreffende Annahme. Zudem hatte ich den Schlüssel dann auch noch über mehrere Tabellen als Fremdschlüssel „durchgeschleift“ – vom damaligen Standpunkt aus war das eine mögliche Lösung die mir eigentlich auch gut gefiel – löste sie doch elegant auch diverse Bezugsprobleme, bzw. ich konnte einen Trigger verwenden um die notwendige Abhängigkeit einer Tabelle von einer anderen automatisch aufzulösen. Es gab also die Basis-Tabelle, eine erweiterte Tabelle und eine Tabelle die in vergleichsweise wenigen Fälle sich auf die erweiterte Tabelle stützte – ein klassisches Prozessgefälle – aus vielen kleinen Datensätzen werden am Ende nur wenige bis zur Blüte oder gar Reife gebracht.

Nun, die Anforderungen haben sich verschoben und die  mittlere/erweiterte Tabelle musste angepasst werden. Wie sich gezeigt hatte brauchten wir für eine spezielle Auswertung nicht nur eine Referenz auf die Basis-Tabelle sondern mindestens zwei, nach eingehender Analyse bin ich auf vier gekommen. Dies liegt in der Tatsache begründet, dass die erweiterte Tabelle eigentlich ein Zusammentreffen mehrer Datensätze aus der Basis-Tabelle abbildet. Das ist mir aber erst im Laufe der weiteren Entwicklung klar geworden – ich denke ich habe das auch beim letzten Mal eher „on the fly“,“mal eben schnell“, „quick’n’dirty“ entwickelt ohne die wahren Beziehungen zu erkennen. Was will man machen – so manches wird einem eben erst im Laufe der Zeit klar.

Erste Konsequenz – der ursprünglich ach so geschickte natürliche Schlüssel über zwei Spalten war nun nicht mehr tragbar – viel zu umständlich: für vier mögliche Referenzen wären es acht Spalten gewesen – Übersichtlichkeit gegen null, zumal die Aussagekraft der jeweiligen Schlüsselpaare zum Gesamtbild nur vergleichsweise wenig beiträgt.- und selbst wenn man es braucht – gejoint ist es dank Indizierung und Foreign Keys doch recht fix. Daher bekommt die Basis-Tabelle neben den natürlichen Spalten ein Surrogat – einen eindeutigen numerischen Primärschlüssel. Wie leicht der einem die Arbeit im weiteren macht ist mir bei der Anpassung des Programmcodes dann aufgefallen.

Wie mit der erweiterten, nunmehr ja eher aggregierenden Tabelle weiter verfahren – außer den vier Spalten für die Referenz – ein natürlicher Primärschlüssel über vier Felder schien mir doch recht gewagt, zumal diese Referenzen sich auch mal im Nachinein noch verändern können. Also auch hier die „künstliche“ Variante mit einem Surrogat.Das entschlackt auch die letzte Tabelle in der Reihe – deren Referenz musste ja auch wieder irgendwie hergestellt werden – nachdem der ursprünglich „durchgereichte“ Schlüssel ja nicht mehr da war musste da eh etwas neues her – auch hier erweist sich die Lösung per Surrogat doch recht tauglich.

Lehrwerte dieser Aktion:

Erstens – natürliche Schlüssel haben einen gewissen Charme – auch wenn sie zur Not aus zwei Spalten bestehen – moderne Datenbank-Systeme stecken das recht gut weg, auch was die Performance betrifft.

Zweitens – eine sorgfältige Analyse und Diskussion eines Entwurfs und die Bedeutung eines Objekts im Gesamtzusammenhang ist durch nichts zu ersetzen – leider zeigt sich hier mal wieder, dass es in meinem Fall keinerlei Prozessdefinition gab und somit natürlich auch die Artefakte nur sehr lückenhaft beschrieben waren. Ein Pflichtenheft wurde aus Kostengründen auch nicht erstellt – stattdessen gab es eine Alt-Datenbank an der man sich orientieren sollte – in bestimmten Dingen war das Design eine Anleitung „wie man es tunlichst nicht machen sollte“ (bei Gelegenheit werde ich dazu mal noch ein paar Zeilen schreiben). Auf einem solchen weichen Untergrund ein solides Fundament und hinterher ein Gebäude zu errichten ist nahezu unmöglich – irgendwo sackt es am Ende doch unangenehm weg.

Drittens – Surrogate sind im ersten Moment oftmals hinderlich und an einigen Stellen „verstellen“ sie teilweise den Blick aufs Wesentliche – man muss sich ggf. die weiterführenden Informationen aus anderen Tabellen erst mal zusammen suchen. Aber sie haben auch eine Menge Vorteile in Sachen Eindeutigkeit und Handhabbarkeit – wenn es einen eindeutigen Wert gibt, erleichtert dass das Auffinden eines Datensatzes und das Instanzieren eines Objekts daraus ganz erheblich.

Mal sehen welche alten Entscheidungen ich demnächst wieder ausgraben muss und mich über meine eigene Schusseligkeit wundern/ärgern darf. In diesem Sinne: Augen auf beim Datenbank-Design.