从 ImageMagick 中的二进制字符串解码图像对象 PHP

Decode image object from binary string in ImageMagick for PHP

我有一个脚本可以下载网站图标并将它们转换为 PNG。

为了处理转换,我正在使用 ImageMagick。我目前的方法包括下载数据、将其写入文件、转换文件,然后删除最初下载的文件。这就是我的意思:

$source = 'http://google.com/favicon.ico';
$image = file_get_contents($source);

// I'd like to skip these lines
$favicon = fopen('favicon.ico', 'w');
fwrite($favicon, $image);
fclose($favicon);

$im = new Imagick();
$im->readimage('favicon.ico');
$im = $im->flattenImages();
$im->setImageFormat('png');
$im->writeImage('favicon.png');
unlink('favicon.ico');

这行得通,但理想情况下,我可以在不将 $image 变量写入文件 favicon.ico 的情况下完成此操作,而我可能只是转换 $image 变量中的数据,然后 $im->writeImage('favicon.png') 在那上面。

我检查了方法 getImageBlob 但是当我尝试时出现了这个错误:

PHP Fatal error:  Uncaught exception 'ImagickException' with message 'no decode delegate for this image format `' @ error/blob.c/BlobToImage/364' in /home/vagrant/test/test_image.php:73
Stack trace:
#0 /home/vagrant/test/test_image.php(73): Imagick->readimageblob('\x00\x00\x01\x00\x02\x00\x10\x10\x00\x00\x01\x00 \x00h...')
#1 {main}
  thrown in /home/vagrant/test/test_image.php on line 73

有什么想法吗?

您需要在读取 blob 之前调用 Imagick::setFormat

<?php
$source = 'http://google.com/favicon.ico';
$image = file_get_contents($source);

$im = new Imagick();
$im->setFormat('ICO');
$im->readImageBlob($image);
$im = $im->flattenImages();
$im->setImageFormat('PNG');
$im->writeImage('favicon.png');

更新

拼合 .ico 图像可能会对包含多个图像的文件产生负面影响。最简单的解决方案是遍历所有图像,并确定要使用的子图像。

$im = new Imagick();
$im->setFormat('ICO');
$im->readImageBlob($image);
for( $idx = 0, $len = $im->getNumberImages(); $idx < $len; $idx++ ) {
    // If this is the sub-image you want, do the following, else skip
    $im->setImageFormat('png');
    $im->setImageIndex($idx);
    $im->writeImage(sprintf('favicon_%d.png', $idx));
}