Denis Potschien 15. Januar 2014

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

Das SVG-Format hat zahlreiche Vorteile: Vor allem, dass es vektorbasiert ist, macht es zu einer Besonderheit unter den gängigen Bildformaten für Browser. Auch wenn alle modernen Browser das Format mittlerweile unterstützen, gibt es gerade beim Internet Explorer noch Probleme. Denn dieser unterstützt SVG erst ab Version 9. Da auch ältere Versionen noch stark verbreitet sind, bietet sich ein Fallback an. Mit PHP und ImageMagick kann ein solches PNG-Fallback automatisch generiert werden.

svg-php-imagemagick

SVG-Dateien an ein PHP-Script schicken

Das Prinzip unserer Fallback-Lösung ist einfach: Per „.htaccess“ wird zunächst dafür gesorgt, dass beim Aufruf von Dateien mit der Endung „.svg“ ein PHP-Script aufgerufen wird. Dieses Script prüft, welcher Browser in welcher Version verwendet wird. Beim Internet Explorer kleiner 9 wird das PHP-Script die SVG-Grafik per ImageMagick ins PNG-Format konvertieren und als solches ausgeben, bei allen anderen als SVG-Format.

Folgende zwei Zeilen in der „.htaccess“ genügen, um per „RewriteRule“ bei entsprechenden Anfragen ein PHP-Script aufzurufen:

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

Im nächsten Schritt wird die Weiterverarbeitung innerhalb des PHP-Scriptes definiert.

Grafik per ImageMagick in PNG konvertieren

Das PHP-Script muss zunächst wissen, welche Datei wiedergegeben werden soll. Hierzu wird der Pfad zur angeforderten SVG-Datei ausgelesen.

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

Die Variable „$datei“ enthält den absoluten Pfad zur SVG-Datei, welche vom Browser angefragt wird. Anschließend wird der Inhalt dieser Datei ausgelesen:

$grafik = file_get_contents($datei);

Die Variable „$grafik“ enthält nun den SVG-Quelltext. Im nächsten Schritt werden Name und Version des verwendeten Browsers ermittelt. Dies kann auf zwei Arten geschehen. Per „$_SERVER["HTTP_USER_AGENT"]“ wird der User-Agent-Header des Browsers ausgelesen. Daraus können Name und Version des Browsers abgeleitet werden.

Alternativ können die Informationen über „get_browser()“ ermittelt werden. Bei Verwendung dieser Methode müssen die Werte aus dem User-Agent-Header nicht selbst extrahiert werden, sondern werden aus der Datei „browscap.ini“ bezogen, die serverseitig zur Verfügung steht. Allerdings stellen nicht alle Provider aktuelle Browserinformationen über diese Datei bereit, sodass man sich im Einzelfall für die etwas aufwändigere Methode entscheiden muss.

$browser = get_browser();

Im Beispiel wird die Variante per „get_browser()“ verwendet. Über eine „if“-Abfrage wird nun die Ausgabe der Grafik gesteuert. Bei allen Versionen des Internet Explorers kleiner 9 wird per ImageMagick die SVG-Grafik konvertiert:

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 neues Bildobjekt von ImageMagick erstellt. ImageMagick ist bei vielen Providern installiert und wird unter anderem von TYPO3 zur internen Bildbearbeitung verwendet. Das Bildobjekt erhält einen transparenten Hintergrund, um Transparenzen der SVG-Grafik zu erhalten. Anschließend wird die SVG-Grafik ausgelesen und ins PNG-Format konvertiert.

Da die im Browser aufgerufene Datei die Endung „.svg“ besitzt, muss dem Browser per Header explizit mitgeteilt werden, dass etwas im PNG-Format ausgegeben wird. Ansonsten wird gegebenenfalls nur der Quelltext der PNG-Datei im Browser dargestellt. Im letzten Schritt wird der Inhalt der PNG-Grafik per „echo“ ausgegeben.

Während beim Internet Explorer kleiner 9 also eine PNG-Grafik wiedergegeben wird, wird bei allen anderen Browsern die SVG-Grafik einfach nur per „echo“ an den Browser geschickt.

Einschränkungen beachten

Damit ImageMagick SVG-Grafiken korrekt und vollständig auslesen kann, müssen einige Einschränkungen beachtet werden. So kann ImageMagick ausschließlich Inline-Stylesheets auslesen. Alles, was über einen Style-Block definiert wird, wird ignoriert. Auch Schriften, die per CSS definiert sind, kann ImageMagick nicht auslesen.

SVG-Animationen gehen bei der Konvertierung natürlich verloren. Auch dies sollte berücksichtigt werden.

Das Fallback per PHP und ImageMagick hat den Vorteil, dass der HTML-Quelltext nicht angefasst werden muss und auf JavaScript verzichtet werden kann. Außerdem muss die Fallback-Grafik nicht manuell bereitgestellt werden.

(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.
Dr. Webs exklusiver Newsletter
Hinweise zum Datenschutz, also dem Einsatz von Double-Opt-In, der Protokollierung der Anmeldung, der Erfolgsmessung, dem Einsatz von MailChimp als Versanddienstleister und deinen Widerrufsrechten findest du in unseren Datenschutzhinweisen.

7 Kommentare

  1. Man kann die Einschränkungen minimieren, wenn man Rootzugriff auf dem Server hat und rsvg installiert. Damit kann man Styleblöcke verwenden und wenn man den Server mit entsprechenden Schriften füttert auch diese.

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

    Nachdem der Inhalt mit file_get_contents() als vermeintliches SVG dann auch direkt ausgegeben wird, kann ich mir damit auch eigentlich geschützte PHP-Files auslesen…da freut man sich wenn Datenbankzugangsdaten oder schlimmeres offen liegen.

  3. Die Basis dieser Iidee haben wir bereits erfolgreich bei einigen Kunden im Einsatz. Um Performance zu „sparen“, cachen wir aber die generierte PNG-Datei auch noch. Wir machen das so, dass wir in der .htaccess überprüfen, ob für das SVG ein PNG vorhanden ist. Wenn ja, wird direkt dieses PNG geliefert. Wenn nicht, wird das Skript aufgerufen, welches die Datei am Server anlegt und ausliefert.

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

Schreibe einen Kommentar zu gustavo123123 Antworten abbrechen

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

Kennst du schon unseren Newsletter?

Hinweise zum Datenschutz, also dem Einsatz von Double-Opt-In, der Protokollierung der Anmeldung, der Erfolgsmessung, dem Einsatz von MailChimp als Versanddienstleister und deinen Widerrufsrechten findest du in unseren Datenschutzhinweisen.