13

I'm trying to use Image-Magick with PHP to convert SVG text into a PNG image. This SVG is a chart generated with NVD3 and I'd like to allow my users to download it as an image.

Basically, I'm sending the SVG data, encoded with JSON to the PHP handler which is supposed to output it as a PNG image.

But, this throws up the following error:

Fatal error: Uncaught exception 'ImagickException' with message 'no decode delegate for this image format `' @ blob.c/BlobToImage/347' in svg2png.php:4 Stack trace: #0 svg2png.php(4): Imagick->readimageblob('

The PHP script for converting the image:

<?php
    /* Derived in part from: http://stackoverflow.com/a/4809562/937891 */
    $svg=json_decode($_REQUEST["svgData"]);
    $im=new Imagick();
    $im->readImageBlob($svg);
    $im->setImageFormat("png24");
    header("Content-Type: image/png");
    $thumbnail = $im->getImageBlob();
    echo $thumbnail;
?>

HTML:

<form id="exportSpendTrendTrigger" method="POST" action="svg2png.php" target="_blank">
    <input id="exportSpendTrendSvgData" type="hidden" name="svgData" />
    <input type="submit" class="btn" value="Export" />
</form>
<div id="spendtrend">
    <svg></svg>
</div>

jQuery:

exportSpendTrend = function (e) {
    //Show the user the PNG-image version for download
    $("#exportSpendTrendSvgData").val( JSON.stringify($("#spendtrend").html().trim()) );
}

$("#exportSpendTrendTrigger").on("submit", exportSpendTrend);

Example SVG, generated by NVD3: http://pastebin.com/Z3TvDK16

This is on an Ubuntu server with PHP 5.3 and Imagick

S P
  • 1,801
  • 6
  • 32
  • 55
  • 3
    Most likely your Imagick install is missing the right delegate. See [ImageMagick convert SVG to PNG not working with RSVG enabled](http://stackoverflow.com/q/11592085) – Pekka Oct 29 '12 at 16:11

2 Answers2

29

svg file text structure needs to be specified for readImageBlob to decode the file. Prepend <?xml version="1.0" encoding="UTF-8" standalone="no"?> to your variable having svg text.

$svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'.$svg;

And you are good to go.

Samsquanch
  • 8,866
  • 12
  • 50
  • 89
Puneet
  • 603
  • 9
  • 18
8

And remember that

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

must be the first line in a variable that contains SVG text. Knowing that may save you some headaches.

dev4life
  • 10,785
  • 6
  • 60
  • 73