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

时间:2015-11-25 12:36:48

标签: php svg imagick

我正在尝试使用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 url。这是一个粉红色背景图片。现在运行我的代码。在白色背景中看到相同的图像..

请帮我解决这个问题。提前多多谢谢。

1 个答案:

答案 0 :(得分: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>image/jpeg - 请检查它。

现在回到您的声明,您无法更改所有文件。我可以提出的是在脚本中解析SVG的XML并用正确的MIME替换所有MIME类型。请注意,这将需要相当多的内存,因为SVG可能很大。请注意MODIFY THE MALFORMED 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();