【问题标题】:Generate SVG Image using svg raw data in imagick php在imagick php中使用svg原始数据生成SVG图像
【发布时间】:2018-05-06 07:07:21
【问题描述】:

我正在尝试使用从 fabric js 获得的 svg 原始数据创建 svg 图像。我使用下面的代码使用 svg 原始数据生成 svg,但它不能正常工作。

public function generate_svg($raw_svg='',$prefix='',$folder_name='card_image')
{
    $file_name = '';       
    if($raw_svg!='')
    {
        try{           
            $file_name = uniqid($prefix).".svg";
            $image = new \Imagick();
            $image->readImageBlob($raw_svg);
            $image->setImageFormat("svg");
            $image->writeImage($folder_name.$file_name);
        } catch (ImagickException $ex) {
            echo $ex->getMessage();
        }
    }
     return $file_name;
}

现在的问题是背景图片如下所示:

那我应该怎么做才能解决这个问题?

它应该如下所示(忽略正方形和圆形),问题是整个背景看起来像黑色而不是背景图像。:

所以问题是背景图片没有加载,所以我是否必须添加额外的库才能做到这一点或其他任何事情?

Imagick 版本:6.7.7

    convert -list delegate | grep svg  

    cdr =>          "uniconvertor' '%i' '%o.svg'; /bin/mv '%o.svg' '%o"
    cgm =>          "uniconvertor' '%i' '%o.svg'; /bin/mv '%o.svg' '%o"
    dot =>          "dot' -Tsvg '%i' -o '%o"
    dxf =>          "uniconvertor' '%i' '%o.svg'; /bin/mv '%o.svg' '%o"
    fig =>          "uniconvertor' '%i' '%o.svg'; /bin/mv '%o.svg' '%o"
    svg =>          "rsvg-convert' -o '%o' '%i"

 convert -list format | grep SVG

 MSVG  rw+   ImageMagick's own SVG internal renderer
  SVG  rw+   Scalable Vector Graphics (XML 2.9.1)
 SVGZ  rw+   Compressed Scalable Vector Graphics (XML 2.9.1)

【问题讨论】:

  • 它应该是什么样子?您尚未提供图片。
  • @MarkSetchell 更新了问题。
  • @MarkSetchell 这里是原始数据:codepen.io/dhavalsisodiya/pen/XewGey
  • 然而,我使用相同的原始数据来生成 png 文件,上面代码中唯一的变化是将图像格式设置为 png24。早些时候,我在 png 对话中遇到了同样的问题,我使用了这个:SVG rw+ Scalable Vector Graphics (XML 2.9.1)。所以我需要安装任何其他将创建 svg 文件的库。
  • 基本的IM转换器。安装 librsvg(首选)或 Inkscape。 ImageMagick 应该能够自动委托给其中之一。您可以使用convert -list delegate | grep svg 进行测试

标签: php svg imagemagick imagick


【解决方案1】:

我最终将字体存储在原始 svg 中,然后使用 fopen 而不是 imagick 创建了 svg 文件。

所以我的 svg 如下所示:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="400" viewBox="0 0 600 400" xml:space="preserve">
<desc>Created with Fabric.js 2.0.0-beta7</desc>
<defs>
<style>
    //... base64 data of font
    @font-face {
        font-family: "Elsie";
        src: url("data:application/font-truetype;charset=utf-8;base64,...")
    }
</style>
</defs>

之后我使用以下方法创建了 svg 文件:

$file_name = uniqid($prefix).".svg";
$file_handle = fopen("$folder_name/".$file_name, 'w');
fwrite($file_handle, $raw_svg);
fclose($file_handle);

【讨论】:

  • 我很好奇您以这种方式获得的文件大小。 base64 编码会减小 ttf 的大小吗?
  • @ccprog base64-encoding 增加文件大小。但是使用该方法所有字体都加载到最终的 svg 图像中。
【解决方案2】:

除了@ccprog 的精彩回答, 我想提一下,您可以使用 phantomjs 生成所需的像素,只需将输入的 html 文件提供给 phantomjs 并输出为 png。

【讨论】:

    【解决方案3】:

    我认为你走错了路。 Image Magick 基本上是一个面向像素的库。虽然渲染背景图像可能是配置问题,但您的图片显示您想要实现的字体“嵌入”没有发生。这才是真正的问题所在。

    您想要实现的是在 SVG 文件中表示字体信息。有两种方法可以做到这一点,对于这两种方法,IM 中绝对不支持:

    • 将字体转换为 SVG 字体格式并将其嵌入到文件中(生成大文件)
    • 将所有字形转换为路径(文本不再可编辑)

    根据您的描述,我认为您应该针对第二个变体。您基本上可以将字符串中的 &lt;text&gt; 元素与 &lt;path&gt; 元素交换,否则会在收到时写出包含嵌入图像数据的 SVG 文件。

    How to convert text to SVG paths? 是对这个问题的一个较老的看法。

    EasySVG for PHP 是一个由字形到路径转换问题产生的库,但前提是您已经拥有 SVG 格式的字体。对于 ttf 等典型的桌面字体格式,您可能首先需要查看字体转换工具,例如 FontForge

    您可能会通过Cairo 获得直接的 svg 数据转换,但这只是一种预感,我还没有使用它。

    最后,作为一种解决方法,您可以将整个任务委托给 Inkscape。它可以在命令行上调用,而无需启动GUI作为

    inkscape in.svg --export-text-to-path --export-plain-svg=out.svg
    

    【讨论】:

      猜你喜欢
      • 2018-05-07
      • 1970-01-01
      • 2019-12-03
      • 2018-03-24
      • 1970-01-01
      • 2012-09-29
      • 2016-06-22
      • 2013-10-17
      相关资源
      最近更新 更多