在PHP中非常糟糕的SVG到PNG转换

时间:2016-03-26 16:09:24

标签: php svg imagemagick png

我正在使用ImageMagick将SVG图转换为PHP中的PNG图像。大多数转换工作,但一些元素(例如阴影)丢失,文本的渲染是丑陋...

Chrome呈现的SVG:

How the SVG looks like in chrome

由PNG中的ImageMagick转换的SVG

How ImageMagick converts the SVG

我首先向PHP添加了模块:

sudo apt-get install php5-imagick
sudo apt-get install libmagickcore-6.q16-2-extra

也许,有比libmagickcore-6.q16-2-extra更好的东西?

在我的PHP文件中:

$image = new Imagick();
$svg2 = file_get_contents('roue1.svg');
$image->readImageBlob('<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . $svg2);
//$image->setImageFormat("png24");
$image->setImageFormat("png");
//$image->resampleimage($width * 10, $height * 10, imagick::FILTER_LANCZOS, 1);
//$image->setresolution($width * 10, $height * 10);
//$image->setimageresolution($width * 10, $height * 10);
//$image->resampleimage($width, $height, imagick::FILTER_LANCZOS, 1);
$image->resizeImage($width, $height, imagick::FILTER_LANCZOS, 1);
$output = $image->getimageblob();
header("Content-type: image/png");
echo $output;

正如你所看到的,我尝试过很多东西,但都失败了:-(

以下是我的SVG的完整大(对不起)代码:

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
  <defs>
    <filter id="b" color-interpolation-filters="sRGB">
      <feFlood flood-opacity=".5" flood-color="#000" result="flood"/>
      <feComposite in="flood" in2="SourceGraphic" operator="in" result="composite1"/>
      <feGaussianBlur stdDeviation="3" result="blur"/>
      <feOffset dx="4" dy="4" result="offset"/>
      <feComposite in="SourceGraphic" in2="offset" result="composite2"/>
    </filter>
    <filter id="a" color-interpolation-filters="sRGB">
      <feFlood flood-opacity=".5" flood-color="#000" result="flood"/>
      <feComposite in="flood" in2="SourceGraphic" operator="in" result="composite1"/>
      <feGaussianBlur stdDeviation="3" result="blur"/>
      <feOffset dx="4" dy="4" result="offset"/>
      <feComposite in="SourceGraphic" in2="offset" result="composite2"/>
    </filter>
    <filter id="c" color-interpolation-filters="sRGB">
      <feFlood flood-opacity=".5" flood-color="#000" result="flood"/>
      <feComposite in="flood" in2="SourceGraphic" operator="in" result="composite1"/>
      <feGaussianBlur stdDeviation="3" result="blur"/>
      <feOffset dx="4" dy="4" result="offset"/>
      <feComposite in="SourceGraphic" in2="offset" result="composite2"/>
    </filter>
    <filter id="d" color-interpolation-filters="sRGB">
      <feFlood flood-opacity=".5" flood-color="#000" result="flood"/>
      <feComposite in="flood" in2="SourceGraphic" operator="in" result="composite1"/>
      <feGaussianBlur stdDeviation="3" result="blur"/>
      <feOffset dx="4" dy="4" result="offset"/>
      <feComposite in="SourceGraphic" in2="offset" result="composite2"/>
    </filter>
  </defs>
  <circle cx="100" cy="100" r="100" fill="#ccc"/>
  <g fill="#fff" fill-rule="evenodd">
    <path d="M94.286 5.714h11.43v188.57h-11.43z"/>
    <path d="M194.286 94.286v11.43H5.716v-11.43zM85.714 185.714L100 200l14.286-14.286H85.714zM85.714 14.286L100 0l14.286 14.286H85.714z"/>
    <path d="M14.286 114.286L0 100l14.286-14.286v28.572zM185.714 114.286L200 100l-14.286-14.286v28.572z"/>
  </g>
  <g font-weight="bold" font-size="100" font-family="Calibri" letter-spacing="0" word-spacing="0" fill="#fff">
    <text style="line-height:125%;-inkscape-font-specification:'Calibri Bold'" x="56.338" y="273.877" opacity=".5" filter="url(#a)" transform="translate(0 -85.714) scale(.57143)">
      <tspan x="56.338" y="273.877">d</tspan>
    </text>
    <text style="line-height:125%;-inkscape-font-specification:'Calibri Bold'" x="253.506" y="274.707" opacity=".5" filter="url(#b)" transform="translate(0 -85.714) scale(.57143)">
      <tspan x="253.506" y="274.707">i</tspan>
    </text>
    <text style="line-height:125%;-inkscape-font-specification:'Sans Bold'" x="246.436" y="423.877" opacity=".5" filter="url(#c)" transform="translate(0 -85.714) scale(.57143)">
      <tspan x="246.436" y="423.877">s</tspan>
    </text>
    <text style="line-height:125%;-inkscape-font-specification:'Sans Bold'" x="60.484" y="423.926" opacity=".5" filter="url(#d)" transform="translate(0 -85.714) scale(.57143)">
      <tspan x="60.484" y="423.926">c</tspan>
    </text>
  </g>
  <path fill="#0074d9" fill-rule="evenodd" d="M85 100h15v15H85z"/>
  <path fill="#2ecc40" fill-rule="evenodd" d="M100 100h25v25h-25z"/>
  <path fill="#ffdc00" fill-rule="evenodd" d="M100 65h35v35h-35z"/>
  <path fill="#ff4136" fill-rule="evenodd" d="M55 55h45v45H55z"/>
  <path d="M55 55l80 10-10 60-40-10z" opacity=".5" fill="none" stroke="#000" stroke-width="2" stroke-dasharray="2"/>
  <rect width="55" height="20" x="143" y="177" ry="5.227" fill="#fff" stroke="#000" stroke-width="1.022"/>
  <path fill="#fff" fill-rule="evenodd" stroke="#000" stroke-width=".587" d="M148 182h10v10h-10z"/>
  <text style="line-height:125%;-inkscape-font-specification:'Sans Bold'" x="161" y="189.899" font-weight="bold" font-size="9" font-family="Verdana" letter-spacing="0" word-spacing="0">
    <tspan x="161.38" y="189.899" font-size="8">Adapté</tspan>
  </text>
</svg>

1 个答案:

答案 0 :(得分:2)

一些想法......

<强>密度/分辨率

如果要设置分辨率/密度,则需要在之前设置加载图像,即在ImageMagick将矢量栅格化为位图之前。之后为时已晚。所以,

convert -density 288 image.svg image.png

会起作用,而这不会

convert image.svg -density 288 image.png

与PHP相同,有:

$imagick = new Imagick();
$imagick->setImageResolution(288,288);
$imagick->readImageBlob();

Inkscape字体

我认为ImageMagick不会理解Inkscape字体,因此建议您通过编辑SVG文件(可能是动态)来更改它,或者在加载SVG之前设置一个后备字体:

convert -density 288 -font FALLBACK image.svg image.png

<强>阴影

不太确定阴影是怎么回事,但要检查ImageMagick正在使用哪个代理,看看你是否可以使用通常做得更好的rsvg代理。

identify -list delegate | grep svg