Spaces. Smartes Cloud Hosting für anspruchsvolle Webprojekte. Loslegen und Spaces testen. Von Mittwald.
Denis Potschien 15. Januar 2014

HTML 5 und SVG: Per PHP und ImageMagick generiertes PNG-Fallback für ältere Browser

Das SVG-Format hat zahl­rei­che Vorteile: Vor allem, dass es vek­tor­ba­siert ist, macht es zu einer Besonderheit unter den gän­gi­gen Bildformaten für Browser. Auch wenn alle moder­nen Browser das Format mitt­ler­wei­le unter­stüt­zen, gibt es gera­de beim Internet Explorer noch Probleme. Denn die­ser unter­stützt SVG erst ab Version 9. Da auch älte­re Versionen noch stark ver­brei­tet sind, bie­tet sich ein Fallback an. Mit PHP und ImageMagick kann ein sol­ches PNG-Fallback auto­ma­tisch gene­riert wer­den.

svg-php-imagemagick

SVG-Dateien an ein PHP-Script schicken

Das Prinzip unse­rer Fallback-Lösung ist ein­fach: Per „.htaccess“ wird zunächst dafür gesorgt, dass beim Aufruf von Dateien mit der Endung „.svg“ ein PHP-Script auf­ge­ru­fen wird. Dieses Script prüft, wel­cher Browser in wel­cher Version ver­wen­det wird. Beim Internet Explorer klei­ner 9 wird das PHP-Script die SVG-Grafik per ImageMagick ins PNG-Format kon­ver­tie­ren und als sol­ches aus­ge­ben, bei allen ande­ren als SVG-Format.

Folgende zwei Zeilen in der „.htaccess“ genü­gen, um per „RewriteRule“ bei ent­spre­chen­den Anfragen ein PHP-Script auf­zu­ru­fen:

RewriteEngine On
RewriteRule \.svg$ /svg.php [L]

Im nächs­ten Schritt wird die Weiterverarbeitung inner­halb des PHP-Scriptes defi­niert.

Grafik per ImageMagick in PNG konvertieren

Das PHP-Script muss zunächst wis­sen, wel­che Datei wie­der­ge­ge­ben wer­den soll. Hierzu wird der Pfad zur ange­for­der­ten SVG-Datei aus­ge­le­sen.

$datei = $_SERVER["DOCUMENT_ROOT"].$_SERVER["REQUEST_URI"];

Die Variable „$datei“ ent­hält den abso­lu­ten Pfad zur SVG-Datei, wel­che vom Browser ange­fragt wird. Anschließend wird der Inhalt die­ser Datei aus­ge­le­sen:

$grafik = file_get_contents($datei);

Die Variable „$grafik“ ent­hält nun den SVG-Quelltext. Im nächs­ten Schritt wer­den Name und Version des ver­wen­de­ten Browsers ermit­telt. Dies kann auf zwei Arten gesche­hen. Per „$_SERVER["HTTP_USER_AGENT"]“ wird der User-Agent-Header des Browsers aus­ge­le­sen. Daraus kön­nen Name und Version des Browsers abge­lei­tet wer­den.

Alternativ kön­nen die Informationen über „get_browser()“ ermit­telt wer­den. Bei Verwendung die­ser Methode müs­sen die Werte aus dem User-Agent-Header nicht selbst extra­hiert wer­den, son­dern wer­den aus der Datei „browscap.ini“ bezo­gen, die ser­ver­sei­tig zur Verfügung steht. Allerdings stel­len nicht alle Provider aktu­el­le Browserinformationen über die­se Datei bereit, sodass man sich im Einzelfall für die etwas auf­wän­di­ge­re Methode ent­schei­den muss.

$browser = get_browser();

Im Beispiel wird die Variante per „get_browser()“ ver­wen­det. Über eine „if“-Abfrage wird nun die Ausgabe der Grafik gesteu­ert. Bei allen Versionen des Internet Explorers klei­ner 9 wird per ImageMagick die SVG-Grafik kon­ver­tiert:

if ($browser["browser"] == "IE" && $browser["majorver"] < 9) {
  $png = new Imagick();
  $png->setBackgroundColor(new ImagickPixel("transparent"));
  $png->readImageBlob($svg);
  $png->setImageFormat("png32");
  header("Content-Type: image/png");
  echo $png;
} else {
  header("Content-Type: image/svg+xml");
  echo $svg;
}

Dazu wird per „new Imagick()“ eine neu­es Bildobjekt von ImageMagick erstellt. ImageMagick ist bei vie­len Providern instal­liert und wird unter ande­rem von TYPO3 zur inter­nen Bildbearbeitung ver­wen­det. Das Bildobjekt erhält einen trans­pa­ren­ten Hintergrund, um Transparenzen der SVG-Grafik zu erhal­ten. Anschließend wird die SVG-Grafik aus­ge­le­sen und ins PNG-Format kon­ver­tiert.

Da die im Browser auf­ge­ru­fe­ne Datei die Endung „.svg“ besitzt, muss dem Browser per Header expli­zit mit­ge­teilt wer­den, dass etwas im PNG-Format aus­ge­ge­ben wird. Ansonsten wird gege­be­nen­falls nur der Quelltext der PNG-Datei im Browser dar­ge­stellt. Im letz­ten Schritt wird der Inhalt der PNG-Grafik per „echo“ aus­ge­ge­ben.

Während beim Internet Explorer klei­ner 9 also eine PNG-Grafik wie­der­ge­ge­ben wird, wird bei allen ande­ren Browsern die SVG-Grafik ein­fach nur per „echo“ an den Browser geschickt.

Einschränkungen beachten

Damit ImageMagick SVG-Grafiken kor­rekt und voll­stän­dig aus­le­sen kann, müs­sen eini­ge Einschränkungen beach­tet wer­den. So kann ImageMagick aus­schließ­lich Inline-Stylesheets aus­le­sen. Alles, was über einen Style-Block defi­niert wird, wird igno­riert. Auch Schriften, die per CSS defi­niert sind, kann ImageMagick nicht aus­le­sen.

SVG-Animationen gehen bei der Konvertierung natür­lich ver­lo­ren. Auch dies soll­te berück­sich­tigt wer­den.

Das Fallback per PHP und ImageMagick hat den Vorteil, dass der HTML-Quelltext nicht ange­fasst wer­den muss und auf JavaScript ver­zich­tet wer­den kann. Außerdem muss die Fallback-Grafik nicht manu­ell bereit­ge­stellt wer­den.

(dpe)

Denis Potschien

Denis Potschien

Denis Potschien ist seit 2005 freiberuflich als Kommunikationsdesigner tätig, seit Anfang 2010 im Kreativkonsulat in Iserlohn, einem Büro für Gestaltung und Kommunikation. Dort betreut er kleine und mittelständische Unternehmen ebenso wie kommunale Körperschaften und Organisationen aus Südwestfalen und dem Ruhrgebiet. Als Webdesigner und -entwickler gehören HTML5 und CSS3 zu seinen Kernthemen, weshalb er dazu 2013 ein Buch geschrieben hat. „Pure HTML5 und CSS3“ richtet sich an alle, die Vorkenntnisse haben, sich aber bisher mit HTML5 und CSS3 nicht oder nur am Rande beschäftigt haben.

7 Kommentare

  1. Man kann die Einschränkungen mini­mie­ren, wenn man Rootzugriff auf dem Server hat und rsvg instal­liert. Damit kann man Styleblöcke ver­wen­den und wenn man den Server mit ent­spre­chen­den Schriften füt­tert auch die­se.

  2. Netter Ansatz, doch die­se Zeile reißt ein gro­ßes Sicherheitsloch auf:
    $datei = $_SERVER[“DOCUMENT_ROOT”].$_SERVER[“REQUEST_URI”];

    Nachdem der Inhalt mit file_get_contents() als ver­meint­li­ches SVG dann auch direkt aus­ge­ge­ben wird, kann ich mir damit auch eigent­lich geschütz­te PHP-Files auslesen…da freut man sich wenn Datenbankzugangsdaten oder schlim­me­res offen lie­gen.

  3. Die Basis die­ser Iidee haben wir bereits erfolg­reich bei eini­gen Kunden im Einsatz. Um Performance zu “spa­ren”, cachen wir aber die gene­rier­te PNG-Datei auch noch. Wir machen das so, dass wir in der .htac­cess über­prü­fen, ob für das SVG ein PNG vor­han­den ist. Wenn ja, wird direkt die­ses PNG gelie­fert. Wenn nicht, wird das Skript auf­ge­ru­fen, wel­ches die Datei am Server anlegt und aus­lie­fert.

  4. Danke für die schö­ne Erklärung!

Schreibe einen Kommentar zu Paul Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.