ImageMagick的SVG输出似乎格式错误

我有一个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();

示例输出:

ImageMagick的SVG输出似乎格式错误

如果我将$format的值更改为pngico,则图像仍然可以正常工作,并使用正确的MIME类型标头发送。当我将格式切换为svg时,将发送正确的MIME类型标头,并且它确实返回 some 种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>

值得注意的是,缺少xmlns元素上的svg属性。也许很奇怪,矩形属性实际上并没有应用于矩形,而是作为某种内联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背景图像,出于某种原因对其进行了内联解析,但是它还引入了以前缺少的方面;尤其是xmlnsviewBox

整个标记看起来与 Inkscape 产生的标记相同。当我在某处读到这是 ImageMagick 可以用来渲染SVG的库之一时,这可能是有道理的。

几乎就像drawImage方法破坏了 Inkscape 解析器一样,它又退回到了一些劣等的引擎上。我希望这会缩小解决方案的路径。

lingchuanhui 回答:ImageMagick的SVG输出似乎格式错误

根据此ImageMagic板,导出到SVG相当麻烦,因为该库用于光栅图像而不是矢量图形。据我了解,SVG输出将始终是具有base64编码二进制数据的图像标签。您要求的解决方法可能如下所示:

$im = new Imagick;
$im->newImage(300,300,new ImagickPixel('#ffffff'));
$im->setImageFormat('svg');

$im1 = new Imagick();
$im1->newImage(300,new ImagickPixel('#ffffff'));
$im1->setImageFormat('png');
$fillColor = new ImagickPixel('#ff0000');
$draw = new ImagickDraw();
$draw->setFillColor($fillColor);
$draw->setStrokeWidth(0);
$draw->setFillOpacity(.5);
$draw->rectangle(50,50,249,249);
$im1->drawImage($draw);

$im->compositeImage($im1->getimage(),Imagick::COMPOSITE_COPY,0);

header('Content-Type: image/svg+xml');

echo $im->getImageBlob();
本文链接:https://www.f2er.com/3056550.html

大家都在问