我有一个PHP脚本,使用ImageMagick生成图标,并以多种格式返回。位图格式(如JPG、PNG甚至ICO)效果很好,但SVG输出会出现一些奇怪的问题。以下是一个最简脚本来说明这个情况:
<?php
$format = 'jpg';
$im = new Imagick;
$im->newImage(300, 300, new ImagickPixel('#ffffff'));
$im->setImageFormat($format);
$draw = new ImagickDraw();
$draw->setStrokeWidth(0);
$draw->setFillColor(new ImagickPixel('#ff0000'));
$draw->setFillOpacity(.5);
$draw->rectangle(50, 50, 249, 249);
$im->drawImage($draw);
header('Content-Type: ' . $im->getImageMimeType());
echo $im->getImageBlob();
样例输出:
如果我将$format
的值更改为png
或ico
,图像仍然能够正常工作,并且会发送正确的MIME类型头。当我将格式切换为svg
时,会发送正确的MIME类型头,并返回某种类型的SVG,但似乎存在格式错误。这是上面示例脚本的输出:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="300" height="300">
stroke-width:0;fill:#FFFF00000000;fill-opacity:0.5; <rect x="50" y="50" width="199" height="199"/>
</svg>
值得注意的是,
svg
元素上的xmlns
属性缺失了。更奇怪的是,矩形属性实际上并没有应用到矩形上,而是被转储为某种内联CSS(但没有正确的上下文来使其作为CSS起作用)。符合预期并且可行的输出结果应该是:
<?xml version="1.0" standalone="no"?>
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
<rect x="50" y="50" width="199" height="199" stroke-width="0" fill="#FF0000" fill-opacity="0.5"/>
</svg>
此外,一个具有正确尺寸的viewBox
属性会更好,但这并不是必须的。
我是否漏掉了什么?也许在以矢量格式呈现之前需要应用某些操作?也许这是个错误?我找不到任何相关信息,希望能给出指导方向。
更新2019-11-25
情节反转。 我之前没有注意到,但当我省略我的示例中的drawImage
步骤时,输出完全不同:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="300px" height="300px" viewBox="0 0 300 300" enable-background="new 0 0 300 300" xml:space="preserve"> <image id="image0" width="300" height="300" x="0" y="0"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsAQAAAABRBrPYAAAABGdBTUEAALGPC/xhBQAAACBjSFJN
AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAd2KE6QAAAA+SURB
VGje7coxAQAACAOg9U9rA1dBf7jJXkw0TdM0TdM0TdM0TdM0TdM0TdM0TdM0TdM0TdM0TdM0TdO0
fytHkUx5BCDW7AAAAABJRU5ErkJggg==" />
</svg>
现在,它创建了一个PNG背景图像,为某种原因内联解析,但也引入了以前缺失的方面,特别是xmlns
和viewBox
。
整个标记看起来与Inkscape生成的东西相同。这可能是有道理的,因为我在某个地方读到这是ImageMagick可以用于呈现SVG的库之一。
就好像drawImage
方法破坏了Inkscape解析器一样,然后它退回到某些劣质的引擎或其他东西。希望这能缩小解决方案的范围。
libmagickcore6-extra
吗?我认为应该已经安装了,因为它可以运行到这一步,但也有可能是旧版本并且支持较少的功能。 - Jeremy Harrislibmagickcore-6.q16-6-extra
软件包运行Linux? - Jeremy Harris