How to read SVG string in Imagick? - php

I have a string containing markup for an svg element.
<svg id="someId" width="300" height="300">
<polygon id="another_id" fill="green" stroke="black" stroke-width="5" points="200,100 131,5 19,41 19,159 131,195 "></polygon>
</svg>
How can I read this string in Imagick and display it.
$svg = '<svg id="someId" width="300" height="300"><polygon id="another_id" fill="green" stroke="black" stroke-width="5" points="200,100 131,5 19,41 19,159 131,195 "></polygon>
</svg>';
$image = new Imagick();
// This is not working.
$image->readImageBlob($svg);
$image->setImageFormat("png");
header("Content-Type: image/png");
echo $image;
How can I read this svg string so that I can proceed with doing other stuffs. Thanks

You have to add <?xml version="1.0"?> in the begining of $svg variable.
This code works for me:
$svg = '<?xml version="1.0"?><svg id="someId" width="300" height="300"><polygon id="another_id" fill="green" stroke="black" stroke-width="5" points="200,100 131,5 19,41 19,159 131,195 "></polygon></svg>';
$image = new Imagick();
$image->readImageBlob($svg);
$image->setImageFormat("png");
header("Content-Type: image/png");
echo $image;

Related

problems using php and dompdf to output svg

I'm trying to display some SVG as a PDF with Dompdf, but the PDF output is blank. Can someone tell me what I need to change?
Here is some example code which produces the error.
<?php
use Dompdf\Dompdf;
$dompdf = new Dompdf();
$statement = '
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
-->
<!-- Title: boxes_and_circles Pages: 1 -->
<svg width="422pt" height="448pt"
viewBox="0.00 0.00 421.50 448.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 444)">
<title>boxes_and_circles</title>
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-444 417.5,-444 417.5,4 -4,4"/>
<!-- A -->
<g id="node1" class="node">
<title>A</title>
<polygon fill="none" stroke="#000000" points="136,-353.5 82,-353.5 82,-317.5 136,-317.5 136,-353.5"/>
<text text-anchor="middle" x="109" y="-331.3" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#000000">A</text>
</g>
<!-- 1 -->
<g id="node7" class="node">
<title>1</title>
<ellipse fill="none" stroke="#000000" cx="102" cy="-234.5" rx="32.5" ry="32.5"/>
<text text-anchor="middle" x="102" y="-230.3" font-family="Helvetica,sans-Serif" font-size="14.00" fill="#000000">1</text>
</g>
<!-- A->1 -->
<g id="edge1" class="edge">
<title>A->1</title>
<path fill="none" stroke="#000000" d="M107.7485,-317.4432C106.9701,-306.2112 105.9343,-291.266 104.9565,-277.1578"/>
<polygon fill="#000000" stroke="#000000" points="108.4424,-276.8319 104.2593,-267.0979 101.4591,-277.316 108.4424,-276.8319"/>
</g>
</svg>
';
$dompdf->loadHtml($statement);
// Render the HTML as PDF
$dompdf->render();
//echo($statement);
// Output the generated PDF to Browser
$dompdf->stream();
?>
If I run echo($statement), the browser outputs this :
The PDF output by Dompdf is completely blank.
If I instead use $statement = "hello, world!", Dompdf correctly outputs hello, world! in the PDF.
What do I need to do to output this SVG image as PDF with Dompdf?
I got it to work by deleting the first line <?xml version="1.0" encoding="UTF-8" standalone="no"?>
Also, in the real code, I had to delete all links that were embedded in the svg.
Furthermore, I had to put the svg into an img tag, and add this base64_encode part as follows :
$html = '<img src="data:image/svg+xml base64,'.base64_encode($statement).'" width="100" height="100" />';
$dompdf->loadHtml($html);
$dompdf->render();
$dompdf->stream();
This was from trial and error, and through reading another post Dompdf not generating pdf properly from SVG

mxGraph, php code to convert XML file into PNG to export image

I'm trying to export an image file (PNG) from mxGraph using PHP.
I successfully send the XML string of the graph to the PHP file and I can parse the XML using the mxUtils::parseXml(); command of the library.
Still the output I receive is unreadable. It's an image file but with nothing inside.
can you help me?
this is the php code i'm using:
$xml = mxUtils::readFile("graphmodel.xml");
$doc = mxUtils::parseXml($xml);
$model = new mxGraphModel();
$graph = new mxGraph($model);
$codec = new mxCodec($doc);
$codec->decode($doc->documentElement, $graph->model);
$image = $graph->createImage(null, "#FFFFFF");
imageInterlace($image, 1);
imageColorTransparent($image, imageColorAllocate($image, 255, 255, 255));
header("Content-Type: image/png");
echo mxUtils::encodeImage($image, 'png');
I don't understand where is the problem.
This is the XML file I upload:
<mxGraphModel dx="876" dy="502" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="CIAO" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="20" y="20" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="4" value="Bella" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="250" y="20" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="5" value="" style="endArrow=classic;startArrow=classic;html=1;entryX=0;entryY=0.5;exitX=1;exitY=0.5;" edge="1" parent="1" source="2" target="4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="20" y="150" as="sourcePoint"/>
<mxPoint x="70" y="100" as="targetPoint"/>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
Thanks for any help you can give me!

Wrong white background when converting SVG to PNG with gradient

I want to convert SVG images to PNG keeping transparency. In the case of solid color shapes works fine, but when the shape is filled with a gradient, then the output image renders an unexpected solid white background.
I want some solution using Imagick library, but some code to preproccess svg code is also acceptable.
Here a minimal example of the issue:
<?php
$svg = <<<SVG
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="100" height="100">
<ellipse style="fill:red" cx="50" cy="50" rx="50" ry="50" />
</svg>
SVG;
$img = new \Imagick();
$img->readImageBlob($svg);
$img->setImageBackgroundColor('transparent');
//IMAGE WITH NICE TRANSPARENT BACKGROUND
$img->writeImage(__DIR__ . '/circle_plain.png');
$svg = <<<SVG
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="100" height="100">
<defs>
<linearGradient
id="linearGradient1">
<stop
style="stop-color:#ff0000;stop-opacity:1;"
offset="0"/>
<stop
style="stop-color:#00ff00;stop-opacity:1;"
offset="1"/>
</linearGradient>
<linearGradient
xlink:href="#linearGradient1"
id="linearGradient2"
x1="0"
y1="50"
x2="100"
y2="50"
gradientUnits="userSpaceOnUse" />
</defs>
<ellipse style="fill:url(#linearGradient2)" cx="50" cy="50" rx="50" ry="50" />
</svg>
SVG;
$img = new \Imagick();
$img->readImageBlob($svg);
$img->setImageBackgroundColor('transparent');
//IMAGE WITH WRONG WHITE BACKGROUND!!
$img->writeImage(__DIR__ . '/circle_gradient.png');

GraphicsMagick PHP extension fails to render Google Fonts in SVG

My Ubuntu 14.04 laptop has GraphicsMagick and the PHP extension (GMagick) installed. When I run the following from the command line,
gm convert -font /usr/share/fonts/truetype/google-fonts/RockSalt.ttf svg_file.svg jpeg_file.jpg
renders the JPEG with the font as desired. However, this PHP code
$gm = new Gmagick();
$draw = new GmagickDraw();
$draw->setfont("/usr/share/fonts/truetype/google-fonts/RockSalt.ttf");
$gm->readImageBlob($svg);
$gm->setImageFormat("jpeg");
$gm->drawimage($draw);
$gm->writeImage($jpgFile);
$gm->clear();
Fails to do the same and creates a JPEG with a default font. What could be the issue here?
This is the SVG:
<?xml version="1.0"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="737" height="521"><defs/> <g class="main"> <title>Main</title> <rect fill="#ffffff" stroke-width="0" x="27.24188" y="429.44421" width="682.51626" height="68.18413" id="svg_2" class="element" opacity="0.75" stroke="#000000"/> <g text-anchor="start" font-family="Rock Salt" fill="#000" font-size="20" class="element textarea" id="svg_3"> <rect opacity="0" stroke-width="0" x="27.24188" y="429.44421" width="682.51626" height="68.18413" id="svg_4"/> <g class="textGroup"> <text class="eol" y="470.98331" x="44.46314" xml:space="preserve">Your memories will last forever</text> </g> </g> </g></svg>
You need to edit GraphicMagick's type.mkg file so the font will load.
https://sourceforge.net/p/graphicsmagick/discussion/250738/thread/5c00e815/
Here is an example of the required format:
https://github.com/CliffsDover/graphicsmagick/blob/master/config/type-windows.mgk.in
<?xml version="1.0"?>
<typemap>
<type
name="Arial"
fullname="Arial"
family="Arial"
weight="400"
style="normal"
stretch="normal"
glyphs="#windows_font_dir#arial.ttf"
/>
<type
name="Arial-Black"
fullname="Arial Black"
family="Arial"
weight="900"
style="normal"
stretch="normal"
glyphs="#windows_font_dir#ariblk.ttf"
/>
<type
name="Arial-Bold"
fullname="Arial Bold"
family="Arial"
weight="700"
style="normal"
stretch="normal"
glyphs="#windows_font_dir#arialbd.ttf"
/>

Imagick SVG cannot load the image

I am getting the trouble about converting the SVG to image by PHP Imagick library.
Here is my code:
$svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg style="overflow: hidden; position: relative;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="754" version="1.1" height="565">
<defs></defs>
<image transform="matrix(1,0,0,1,0,0)" preserveAspectRatio="none" x="0" y="0" width="754" height="565" xlink:href="http://1439.demo.tekk3.com/wp-content/uploads/2012/10/capapix_Harley_Davidson_FLSTCI_-_Heritage_Classic.jpg"></image>
</svg>';
$im = new Imagick();
$im->readImageBlob($svg);
$im->setImageFormat("jpeg");
$im->writeimage($attached_file);
$im->clear();
$im->destroy();
And the result is an image with only white background. There are no any other images as SVG showing.
If i put the text tag into the SVG string, only the text rendered in the white background. The image is still missing.
I have installed the php5-imagick, libxml2, librsvg2-bin
Are there any other extensions that i need to install to get the correct result?
Or is there any problem in my code?
I found workaround. I use base64 image content instand of image path.
$svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="754" version="1.1" height="565">
<image x="0" y="0" width="754" height="565" xlink:href="'.imageToBase64('icons-weather_01.png').'"></image>
</svg>';
function imageToBase64($path) {
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
return 'data:image/' . $type . ';base64,' . base64_encode($data);
}
It if possible to use local image or web url.
You should not use link to the image if you want Imagick to consider your images when converting.
instead use the base64 encoded data corresponding to those images. this will work.
I had this problem and ended up here, didn't see the solution in the comment (had to click on 'show more comments') until I'd fixed it myself anyway, so thought it might be worth posting it as an answer (as well as upvoting):
As #Phuc-Pham discovered, the problem is that Imagick wants the whole server path, not a path relative to CWD or HTTP document root in the href attribute.
So using his code above the solution should be something along the lines of:
$svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg style="overflow: hidden; position: relative;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="754" version="1.1" height="565">
<defs></defs>
<image transform="matrix(1,0,0,1,0,0)" preserveAspectRatio="none" x="0" y="0" width="754" height="565" xlink:href="/path/to/htdocs/wp-content/uploads/2012/10/capapix_Harley_Davidson_FLSTCI_-_Heritage_Classic.jpg"></image>
</svg>';
Hope that's useful.

Categories