Search code examples
phpsvgimagickimagemagick-convert

Converting SVG to PNG with ImageMagic ignores fill pattern url


I am using PHP's Imagick class to convert an SVG to PNG.

The conversion succeeds but seems to ignore any fill patterns. Here is my code:

<?php

$svg = <<<SVG
<?xml version="1.0"?>
<svg>
    <defs>
        <pattern id="myPattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
            <rect width="20" height="20" fill="#ffffff" /> 
            <circle cx="10" cy="10" r="5" stroke="#0000bb" fill="#dd8d8d" /> 
        </pattern>
    </defs>
    <text y="100%"
        stroke="#ff0000"
        fill="url('#myPattern')"
        font-size="40pt">
        Hello <tspan style="font-style: italic">SVG</tspan> world!
    </text>
</svg>
SVG;

try{

    $image = new Imagick();
    $image->setBackgroundColor(new ImagickPixel('transparent'));
    $image->readImageBlob( $svg );
    $image->setImageFormat('png32');
    $image->setImageCompressionQuality(100);

    file_put_contents('text-fill-example.png', $image);
}
catch(ImagickException $e){
    error_log($e);
}

In the above example, the letters should contain a dotted pattern. If you open the above svg code as a file in Inkscape, the pattern shows correctly. Also if you embed the svg code into html it shows the pattern correctly in modern browsers.

The pattern is also ignored if I try to convert from the command line:

$ convert -verbose text-fill-example.svg text-fill-example.png 
text-fill-example.svg SVG 358x36 358x36+0+0 16-bit DirectClass 433B 0.020u 0:00.030
text-fill-example.svg=>text-fill-example.png SVG 358x36 358x36+0+0 16-bit PseudoClass 256c 8.19KB 0.010u 0:00.009

$ convert --version
Version: ImageMagick 6.7.7-10 2014-03-06 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP    

Does anyone know anything about this?


Solution

  • Turns out my SVG code was not entirely valid. I used the W3C validator to end up with some markup that is 100% valid and now it works:

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
        <defs>
            <pattern id="myPattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
                <rect width="20" height="20" fill="#ffffff" /> 
                <circle cx="10" cy="10" r="5" stroke="#0000bb" fill="#dd8d8d" /> 
            </pattern>
        </defs>
        <text y="100%"
            stroke="#ff0000"
            fill="url(#myPattern)"
            font-size="40pt">
            Hello <tspan style="font-style: italic">SVG</tspan> world!
        </text>
    </svg>