Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Imagick通过rsvg转换SVG会在PHP中呈现空白图像,但在命令行中显示ok_Php_Svg_Imagemagick_Imagick_Librsvg - Fatal编程技术网

Imagick通过rsvg转换SVG会在PHP中呈现空白图像,但在命令行中显示ok

Imagick通过rsvg转换SVG会在PHP中呈现空白图像,但在命令行中显示ok,php,svg,imagemagick,imagick,librsvg,Php,Svg,Imagemagick,Imagick,Librsvg,我读过一系列的问题和网络文章,但似乎遇到了困难。我已将问题简化为一个非常简单的SVG文件,其中包含一个图像。当通过imagick从PHP转换时,图像呈现为空白,但从使用相同rsvg引擎的命令行,图像呈现良好 这个项目在我当地的Fedora开发机器上运行得很好,只有在Centos上投入生产时,我才遇到了这个问题 环境:Centos 6.2服务器,使用PHP fpm的PHP 5.6.36,使用ImageMagick库版本6.7.8-9 2016-06-16的Imagick模块版本3.4.3 注意:我

我读过一系列的问题和网络文章,但似乎遇到了困难。我已将问题简化为一个非常简单的SVG文件,其中包含一个图像。当通过imagick从PHP转换时,图像呈现为空白,但从使用相同rsvg引擎的命令行,图像呈现良好

这个项目在我当地的Fedora开发机器上运行得很好,只有在Centos上投入生产时,我才遇到了这个问题

环境:Centos 6.2服务器,使用PHP fpm的PHP 5.6.36,使用ImageMagick库版本6.7.8-9 2016-06-16的Imagick模块版本3.4.3

注意:我的apache服务器根本不会占用或启动文件系统,因此所有正常的路径引用都应该可以正常工作,例如,它使用绝对路径名写入web根目录中的日志文件

$ identify -list format | grep -i svg
     MSVG  SVG       rw+   ImageMagick's own SVG internal renderer
      SVG  SVG       rw+   Scalable Vector Graphics (RSVG 2.39.0)
     SVGZ  SVG       rw+   Compressed Scalable Vector Graphics (RSVG 2.39.0)


$ identify -list delegate | grep -i svg
        cdr =>          "uniconvertor" "%i" "%o.svg"; mv "%o.svg" "%o"
        dot =>          "dot" -Tsvg "%i" -o "%o"
        svg =>          "rsvg-convert" -o "%o" "%i"
因此,我相信“SVG”格式表示它将使用RSVG从PHP进行转换

我的SVG(从Inkscape保存):

使用
rsvg convert
进行相同操作(如上面学员输出中所示):

结果:两次命令行尝试,
cli.jpg
rsvg convert.jpg
,显示的图像都很好。来自PHP的尝试显示一个空白输出,即
元素没有呈现

没有抛出异常,也没有我可以找到的错误输出

我试过:

  • 使
    xlink:href
    成为具有绝对路径的
    文件://
    URL,即
    xlink:href=”file:///home/myuser/public_html/test/svg-problem/image.jpg“
  • 使
    xlink:href
    成为相对于当前目录路径的
    文件://
    URL,即
    xlink:href=”file://./image.jpg“
  • 使
    xlink:href
    成为无路径的
    文件://
    URL,即
    xlink:href=”file://image.jpg“
  • 使用
    $im->setFormat('RSVG')
    强制使用“RSVG”。。它引发异常,无法设置格式。我不明白为什么
由于通过PHP完成的转换没有调用
setFormat
,并且上面显示的格式列表表示默认情况下将使用RSVG,因此我认为它使用的是RSVG,即使我尝试强制使用RSVG格式失败

我已经读到,当rsvg库无法加载文件时,您可以重新编译它以显示更多错误输出,但是在我的生产cPanel管理的服务器上,我非常不愿意尝试重新编译任何东西


你知道下一步该怎么做吗?把我的头发拔出来:)

这里的问题是,我不知道ImageMagick如何详细使用librsvg接口。但在最近的一次调查中,有几件事引人注目。根据我在Gnome系统中观察到的情况,虽然这些段落只是在v2.42文档中添加的,但我认为它们也适用于较旧的版本

在处理SVG时,如果引用的文件与基础文件位于同一目录或其子目录中,则librsvg只会加载这些文件……这样,恶意SVG文件就不能包含位于上面目录中的文件

如果内存中已经有SVG数据,则可以创建内存输入流……注意,在这种情况下,为内存中的SVG数据指定基本文件非常重要。Librsvg使用base_文件解析指向外部内容(如光栅图像)的链接

根据ImageMagick实现,这将导致两种可能的解决方案:

  • 直接从包含以下内容的文件加载SVG:

     $im->readImage('src.svg');
    
  • 使用字符串,但在中设置第二个文件参数

     $im->readImageBlob('<?xml version="1.0"?>' . $svg, 'src.svg')
    
    $im->readImageBlob(''.$svg',src.svg')
    

  • 顺便提一下,
    $im->setFormat('RSVG')
    没有任何意义,因为“RSVG”只是库的名称,而不是文件格式。

    我无法通过IMagick PHP库工作,但使用
    proc_open
    会产生与从命令行调用时完全相同的结果:

    convert rsvg:src.svg cli.jpg
    
    $imgPath='/path/to/image.svg';
    $svg=文件获取内容($imgPath);
    // ... 如果需要,在此处操作svg内容
    $descriptorSpec=数组(
    0=>数组(“管道”、“r”),//STDIN
    1=>数组(“管道”,“w”),//标准输出
    2=>数组(“管道”,“w”),//STDERR
    );
    //fd:0-STDIN,fd:1:STDOUT,
    //svg:和png:告诉ImageMagick输入/输出格式
    $cmd=“convert svg:fd:0 png:fd:1”;
    $proc=proc_open($cmd,$descriptorSpec,$pipes,null,null);
    如果(!is_资源($proc)){
    抛出新的RuntimeException(“proc_open:$cmd失败”);
    }
    fwrite($pipes[0],$svg);
    fclose($pipes[0]);
    $png=流内容($pipes[1]);
    fclose($pipes[1]);
    如果(!$png){
    抛出新的RuntimeException(“命令未返回任何输出:$cmd”);
    }
    $stdErr=流内容($pipes[2]);
    fclose($pipes[2]);
    如果($stdErr){
    抛出新的运行时异常(“命令$cmd返回错误:$stdErr”);
    }
    $exitStatus=proc_close($proc);
    如果($exitStatus){
    抛出新的RuntimeException(“命令返回$exitStatus:$cmd”);
    }
    //使用适当的标题呈现PNG,或保存到文件,或返回等
    
    将输出写入
    out.jpg
    但设置
    $im->setImageFormat('png24')
    ?此外,您确定直接从rsvg convert生成的文件确实是jpg吗?命令行工具不提供这种输出格式。从我的尝试,我得到了一个PNG,即使我设置了一个名称out.jpg,我遇到了线程。也许可以尝试用
    $im->readImage()
    加载图像。谢谢@ccprog,很好,是的,我在示例程序中错误地键入了jpg,我已经相应地编辑了我的问题。但是,将其固定到
    .png
    仍然会导致500x500像素的空白图像。有趣的是,根据linux的
    file
    命令,我的原版输出的
    .jpg
    看起来确实是一个JFIF映像,通过检查它的头字节,我不确定这与您的体验有什么不同。不管怎么说,这都是一条红鲱鱼:)@ccprog您的
    $im->readImage()
    建议似乎是正确的。添加
    我明白你的意思。
    
    rsvg-convert src.svg -o rsvg-convert.jpg
    
     $im->readImage('src.svg');
    
     $im->readImageBlob('<?xml version="1.0"?>' . $svg, 'src.svg')