使用Imagick将SVG转换为PNG的问题

3
我正在尝试使用imagick将svg转换为png图像。这是我正在使用的代码。
<?php
$usmap = 'http://yatnam.com/demo/vh/card2_1.svg';
$svg = file_get_contents($usmap);
$im = new Imagick();
//$im->setBackgroundColor(new ImagickPixel('transparent'));
$im->readImageBlob($svg);
$im->setImageFormat("png32");
$im->setImageCompressionQuality(100);
$im->resizeImage(720, 445, imagick::FILTER_LANCZOS, 1);
$base64=base64_encode($im);
$im->clear();
$im->destroy();
?>
<img src="<?php echo 'data:image/jpg;base64,' . $base64;?>" />

我的SVG图像包含许多其他的base64编码的图片...如果不是PNG格式,这些图片将无法正确转换。

为了确切理解问题,请直接浏览SVG网址。它是一个粉色背景的图片。现在运行我的代码。看到相同的图片,在白色背景下...

请帮我解决这个问题...非常感谢您的帮助。

1个回答

1

您是否有访问SVG文件的权限?或者能够将其下载/保存到本地,然后进行更改?

xlink:href="data:image/jpeg;base64

在第一个<image>标签中。
xlink:href="data:image/png;base64

你需要引用本地下载并更改的副本吗?

另一种显示需要更改的方法在这里:

enter image description here

我得到了以下内容:

enter image description here

更新:我想再次强调,您提供的SVG文件作为示例具有粉色背景作为<image>,其MIME类型是错误的,就像我在评论中所说的那样。您描述的问题正是由此引起的,无论图像来源有多可靠。您可以通过复制SVG中第一个<image>的base64值,解码并保存,然后使用任何编辑器打开它来检查,您将会看到这个:

enter image description here

这是一个PNG签名,而不是JPEG。然而,在SVG中的第一个标签中有image/jpeg,请检查一下。
现在回到你说无法更改所有文件的问题。我可以建议在你的脚本中解析SVG的XML,并用正确的MIME类型替换所有MIME类型。请注意,这将需要相当多的内存,因为SVG可能很大。请注意在“修改格式错误的SVG”注释之间的新代码。
$usmap = 'http://yatnam.com/demo/vh/card2_1.svg';
$svg = file_get_contents($usmap);

/////////////////// MODIFY THE MALFORMED SVG ///////////////////////

$dom = new DomDocument();
$dom->loadXML($svg);
foreach($dom->getElementsByTagName('image') as $image) {
    $encoded = $image->attributes->getNamedItem('href')->value;
    if(!empty($encoded)) {
        $binary = base64_decode(substr($encoded,strpos($encoded,'base64,') + 7));
        $info = getimagesizefromstring ($binary);

        $image->setAttributeNS('http://www.w3.org/1999/xlink','xlink:href','data:'.$info['mime'].';base64,' . base64_encode($binary));
    }
}

$svg = $dom->saveXML();

/////////////////// MODIFY THE MALFORMED SVG ///////////////////////

$im = new Imagick();
//$im->setBackgroundColor(new ImagickPixel('transparent'));
$im->readImageBlob($svg);
$im->setImageFormat("png32");
$im->setImageCompressionQuality(100);
$im->resizeImage(720, 445, imagick::FILTER_LANCZOS, 1);
$base64=base64_encode($im);
$im->clear();
$im->destroy();

嗨Alexey,谢谢您的回答...如果图像是PNG格式,它可以正常工作...我已经知道了这一点...但是需要在其他格式中工作...为什么它不能在任何其他格式中工作..??这就是我想知道的事情。 - Febin Thomas
我的意思是你在SVG base64编码中拥有的那张图片在SVG中具有错误的MIME类型。也就是说,SVG文件可能存在格式问题。 - Alexey
这只是一个用于调试的示例SVG图像。您可以在任何其他SVG图像中尝试它。如果我没记错的话,使用Base64图像(除PNG图像外)也会出现同样的问题。 - Febin Thomas
抱歉,我不理解你上一条评论的意思。如果你替换base64代码,那会导致图像损坏。我的意思是仅更改图像的类型,其他保持不变。 - Alexey
嗨,我必须处理很多其他的SVG图像,所以要在所有文件中更改MIME类型会非常困难,而且甚至网站用户也可以上传SVG图像,我不能限制他们只能上传特定MIME类型的文件。 - Febin Thomas
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接