SVG zu PNG konvertieren in PHP
Ich zeige euch wie man SVG zu PNG konvertieren kann. Für mein letztes Projekt war das notwendig, da ich ein in einem Editor selbst erstelltes Avatarbild im SVG Format in ein externes Programm importieren musste. Dieses hatte aber massive Probleme bei der SVG Darstellung, deshalb entschied ich mich zur Konvertierung in ein besser unterstütztes PNG Format. In PHP auf einem Linux Server kein Problem!
SVG zu PNG konvertieren in PHP
Aus meinem Avatar Programm exportiere ich das Ergebnis im SVG Format. Dieses hat den Vorteil, dass man über PHP Code sehr einfach Änderungen vornehmen kann. Im einfachsten Fall färbt man beispielsweise die Kleidung um oder ändert den Hintergrund. Das erzeugte SVG kann man auf der Webseite einfach einbinden und im Browser ausgeben. Das angeschlossene phpBB Forum kennt leider noch kein SVG Bildformat, deshalb muss ich das SVG übe rein PHP Skript bei der automatischen Erstellung beziehungsweise Aktualisierung des Forumbenutzers als PNG neu erstellen.
Der vollständige Source Code aus meinem PHP Skript:
//generate png from svg and save to forum $im = new Imagick(); $svg = file_get_contents($filename); $im->readImageBlob('<?xml version="1.0" encoding="UTF-8" standalone="no"?>'.$svg); $im->setImageBackgroundColor(new ImagickPixel('transparent')); $im->setImageFormat("png24"); $im->resizeImage(90, 90, imagick::FILTER_LANCZOS, 1); $im->writeImage($phpbb_root_path."images/avatars/upload/".$avatar_salt."_".$forum_user_id.".png"); $im->clear(); $im->destroy();
Wie man sieht benötigt man die Imagick Klasse. Am Server muss die php Imagick Erweiterung installiert sein. Nur diese kann mit SVG Dateien fast fehlerfrei arbeiten. Ein Update auf die aktuellste Version ist in jedem Fall zu empfehlen. Ich konnte ohne Probleme auf meinem shared Hosting damit arbeiten, ob diese üblicherweise vom Hoster vorinstalliert ist kann ich nicht sagen. Auf meinem selbst administrierten Linux Server habe ich die Erweiterung manuell nachinstalliert.
Konvertierung im Detail
Zuerst lädt man das SVG ein und speichert den Dateiinhalt als String in der Variable $svg. Dieses übergibt man der readImageBlog() Funktion von Imagick. In meinem Fall fehlte beim SVG die Definitionszeile für XML Dateien, was vermutlich normal ist. Leider akzeptiert readImageBlog() die übergebenen Daten ohne diese nicht.
Mein SVG verwendet als Hintergrund nichts, diese Fläche soll auch in der PNG transparent bleiben. Um das zu gewährleisten setzen wir manuell mit setImageBackgroundColor() diese Farbe auf transparent.
Als Bildformat habe ich mich mit setImageFormat() für png24 entschieden. Eventuell kann man da auch andere Werte setzen, für mein transparentes PNG war dieser Wert optimal. Das SVG ist eine Vektorgrafik und kann nach belieben skaliert werden. Standardmäßig wird in meinem Fall das SVG mit 600×600 Pixel ausgegeben. Im phpBB Forum akzepiere ich nur Avatarbilder mit 90 Pixel Seitenlänge, deshalb wird das Bild mit resizeImage() auf eben diese Größe heruntergerechnet.
Mit writeImage() geben wir das fertige PNG Bild noch in einer Datei aus. In meinem Fall wird das Bild direkt in den Avatar Ordner des Forums kopiert. Als Dateiname wird die ID des Forumsbenutzers verwendet. Mit dem Namen abgespeicherte Avatarbilder sind dann umgehend im Forum sichtbar.
Fazit
SVG zu PNG konvertieren ist mit PHP sehr einfach. Die größten Probleme hatte ich mit der Installation von Imagick und mit dem Bildcache im Forum.
Welches Programm verwendest Du für die Avatarerstellung?
das gibts recht günstig zu kaufen und heißt: SVG Avatars Generator
Um bei höheren Auflösungen bessere Ergebnisse zu erhalten, sollte man zuerst die Auflösung setzen und dann erst konvertieren. Dazu die Reihenfolge beiden folgenden Befehle ändern:
$im->setImageFormat(„png24“);
$im->resizeImage(900, 900, imagick::FILTER_LANCZOS, 0.1);
For an alternative solution, that correctly deals with size and resultion:
$svg = “.$svg;
$im = new Imagick();
$im->readImage(„/path/to/image.svg“); // OR $im->readImageBlob($svg);
$res = $im->getImageResolution();
$x_ratio = $res[‚x‘] / $im->getImageWidth();
$y_ratio = $res[‚y‘] / $im->getImageHeight();
$im->removeImage();
$im->setResolution($width_in_pixels * $x_ratio * 2.54, $height_in_pixels * $y_ratio * 2.54);
$im->readImage(„/path/to/image.svg“); // OR $im->readImageBlob($svg);
// Now you can do anything with the image, such as convert to a raster image and output it to the browser:
$im->setImageFormat(„png“);
header(„Content-Type: image/png“);
echo $im;