我已经阅读了一系列问题和网络文章,但似乎遇到了一堵砖墙。我已将我的问题简化为一个非常简单的 SVG 文件,其中包含一个图像。当通过 imagick 从 PHP 转换时,图像呈现为空白,但从命令行使用相同的 rsvg 引擎呈现良好。
这个项目在我当地的 Fedora 开发机器上运行得就像一个魅力,只有当我在 Centos 上进行生产时才遇到这个问题。
环境:Centos 6.2 服务器,PHP 5.6.36 使用 php-fpm,Imagick 模块版本 3.4.3 使用 ImageMagick 库版本 6.7.8-9 2016-06-16
注意:我的 apache 服务器根本没有监狱或 chroot 文件系统,所以所有正常的路径引用应该可以正常工作,例如它使用绝对路径名写入 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 保存):
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="620mm" height="640mm" viewBox="0 0 620 640" version="1.1" id="svg28" inkscape:version="0.92.3 (2405546, 2018-03-11)" sodipodi:docname="radcover-620x640b.svg">
<defs id="defs22"/>
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.24748737" inkscape:cx="1386.1321" inkscape:cy="1147.0763" inkscape:document-units="mm" inkscape:current-layer="layer1" showgrid="false" inkscape:window-width="1920" inkscape:window-height="1016" inkscape:window-x="2048" inkscape:window-y="27" inkscape:window-maximized="1" inkscape:snap-global="false"/>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,343)">
<image fill-opacity="0" stroke="none" stroke-opacity="0" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" x="54.336063385009766" y="-280.25213623046875" width="280.0984802246094" height="175.3288116455078" preserveAspectRatio="none" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="image.jpg" data-number="1" transform="matrix(0.98887052,-0.14877865,0.14877865,0.98887052,0.00000000,0.00000000)"/>
</g>
</svg>
我的PHP代码:
<?php
$widthPx = 500;
$heightPx = 500;
$outFilename = 'out.png';
$svg = file_get_contents('src.svg');
$im = new Imagick();
$im->readImageBlob('<?xml version="1.0"?>' . $svg);
$im->setImageFormat('png24');
$im->resizeImage($widthPx, $heightPx, imagick::FILTER_LANCZOS, 1);
$im->writeImage($outFilename);
echo "Done.\n";
来自命令行的相同尝试:
convert rsvg:src.svg cli.jpg
相同的使用rsvg-convert
(如上面的代表输出所示):
rsvg-convert src.svg -o rsvg-convert.jpg
结果:命令行尝试cli.jpg
和rsvg-convert.jpg
,都显示图像很好。PHP 的尝试显示空白输出,即<image>
元素未呈现。
没有抛出异常,也没有我能找到的错误输出。
我努力了:
- 使
xlink:href
成为file://
具有绝对路径的 URL,即xlink:href="file:///home/myuser/public_html/test/svg-problem/image.jpg"
- 使
xlink:href
成为file://
相对于路径当前目录的URL,即xlink:href="file://./image.jpg"
- 将其设为没有路径
xlink:href
的URL,即file://
xlink:href="file://image.jpg"
- 使用 .强制使用“RSVG”
$im->setFormat('RSVG')
会引发异常Unable to set format
。我不明白为什么。
由于通过 PHP 的转换无需调用即可完成setFormat
,并且上面显示的格式列表表示默认情况下它将使用 RSVG,我认为它正在使用 RSVG,即使我尝试强制 RSVG 格式失败。
我已经读到您可以重新编译 rsvg 库以在无法加载文件时显示更多错误输出,但是在我的生产 cPanel 托管服务器上,我非常不愿意尝试重新编译任何东西。
任何想法接下来要尝试什么?把我的头发拉在这里:)