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

标签 php svg imagemagick png

我正在使用 ImageMagick 在 PHP 中将 SVG 图形转换为 PNG 图像。大多数转换都有效,但缺少一些元素(例如阴影)并且文本的呈现很难看......

Chrome 渲染的 SVG :

How the SVG looks like in chrome

ImageMagick转换成PNG格式的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>

最佳答案

一些想法......

密度/分辨率

如果您想设置分辨率/密度,您需要在加载图像之前设置它,即在 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

关于php - PHP 中非常糟糕的 SVG 到 PNG 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36237561/

相关文章:

css - 与 Chrome 相比,Safari 的投影非常小

css - 等效于 CSS 3's ' 过滤器 : grayscale(x)' with ImageMagick

ffmpeg - 从图像生成影片时指定背景颜色

javascript - 使用 php 用 js 创建警报

javascript - 如何将 POST 变量添加并保存到 Qualtrics?

php - 通过PHP验证用户

php - 如何仅从 MySql 数据库表中获取特定行

html - 具有宽度/高度的 SVG 在 IE9/10/11 上无法缩放

image - 使用 Imagemagick 将 SVG 转换为 JPEG,缺少外部光栅图形

imagemagick - 将许多 png 转换为多页 tiff