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

Issues to convert SVG to PNG using Imagick

我正在尝试使用 imagick.This 将 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 directly.It 是带有粉红色的图像 background.Now 运行 我的代码。在白色背景中查看相同的图像..

请帮我解决这个问题。非常感谢。

您有权访问 SVG 文件吗?或者您可以 download/save 在本地,然后更改

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

第一名<image>

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

并引用您本地下载和更改的副本?

显示您需要更改的内容的另一种方式是:

然后我得到以下信息:

更新: 我想再说一遍,您作为示例提供的 SVG 文件的粉红色背景为 <image> 错误 MIME类型,我在评论里说了。无论图像源多么可靠,都会因此而出现您描述的问题。您可以通过复制 SVG 中第一个 <image> 的 base64 值来检查它,对其进行解码并保存,然后用任何编辑器打开它,您将看到:

这是 PNG,不是 JPEG 签名。但是,SVG 中的第一个 <image>image/jpeg - 检查它。

现在回到您声称不能更改所有文件的问题。我可以建议的是在您的脚本中解析 SVG 的 XML 并将所有 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();