Denis Potschien January 15th, 2014

HTML 5 and SVG: Providing a PNG Fallback with PHP and ImageMagick

Using SVG in web design has many advantages. Being a vector format is the biggest and has it standing out from the crowd of other image formats. You could have guessed, though, that while modern browsers do already support SVG, the good ole Internet Exploder doesn't, at least not below version 9. As older versions of Internet Explorer are still out there in the wild, you should always consider implementing a fallback solution. Using PHP and ImageMagick makes it a snap to provide a fallback to PNG..

svg-php-imagemagick

Sending SVG to a PHP script

The principle of our fallback solution is simple. First we make sure, that files with the extension .svg are sent to a PHP script. This script will then check the visitor's browser. In case it detects an Internet Explorer below version 9, it calls ImageMagick to convert the SVG to a common readable PNG. All other browsers will be provided with the native SVG. This can easily be achieved by creating a .htaccess like this. Only two lines of code are needed to set this so-called RewriteRule into effect:
RewriteEngine On
RewriteRule \.svg$ /svg.php [L]
In the next step we will tell the PHP how to process the file.

Converting SVG to PNG via ImageMagick

Obviously, our script will need to know, which file to process. It does this by reading its path.
$file = $_SERVER["DOCUMENT_ROOT"].$_SERVER["REQUEST_URI"];
The variable $file will then contain the full path to the SVG file requested by the browser. Now the contents of the file will be read:
$image = file_get_contents($file);

The variable $image“ then contains the SVG source code. After that we will detect name and version of the browser used. We have two ways to do so.

Either we use $_SERVER["HTTP_USER_AGENT"] to read the user-agent header, which enables us to conclude name and version of the browser. Or we go for get_browser(), which needs no conclusions, but reads the browser information from server-side browscap.ini. Unfortunately not all providers actually provide accurate recent information this way. Do be more secure as to getting correct information, you might want to go for using user-agent.

$browser = get_browser();
In this example we use get_browser(). If the detected browser is a version of Internet Explorer and below 9, ImageMagick will convert the SVG to PNG, Else not:
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;
}

To do so, ImageMagick needs to create a new object via new Imagick(). ImageMagick is quite common and should be available in most standard hosting plans. Typo3 e.g. uses ImageMagick for all the internal image editing. On conversion, the image object will have a transparent background to keep transparencies of the original SVG. Then the source code gets read and the PNG format is created.

Unfortunately the file extension will still be .svg, which makes it necessary to force the browser to output PNG. This is done in the header. If we wouldn't care for that step, we'd only see the PNG source code.

In the last step we output the PNG simply via echo. This is true for the SVG also. It all depends on the result of the detection done.

Restrictions

To make sure, ImageMagick is able to read SVG correctly and completely, make sure to meet the preconditions. ImageMagick is not able to read style blocks and will ignore its definitions. ImageMagick is only able to read inline styles. Fonts defined via CSS will be ignored, too. The same is true for animations. Using PHP and ImageMagick allows you to leave the HTML untouched, needs no JavaScript and needs no manually provided PNG.

(dpe)

Denis Potschien

Denis works as a freelance web designer since 2005.

One comment

  1. > Unfortunately not all providers actually provide accurate recent information this way. Do be more secure as to getting correct information, you might want to go for using user-agent.

    WRONG. user-agent is client data. thats why you can’t be sure, if IE is requesting.

    > Unfortunately

    It’s year 1 after Snowden. The less client informations you provide, the better.

Leave a Reply

Your email address will not be published. Required fields are marked *