我目前正在尝试使用PHP-Imagick将ICO文件转换为16x16 px PNG。到目前为止,我已经尝试过:
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$im->writeImages($targetFile, true);
这部分起作用。问题是,ICO文件可能包含多个图像,因此上面的代码创建了多个PNG文件
适用于各种尺寸。没关系,但是随后,我需要找到接近16x16像素的像素,将其缩小(如果需要)并删除所有其他像素。为此,我已经尝试了一些方法,这就是我目前遇到的问题:
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$count = $im->getNumberImages();
if ($count > 1) {
for ($x = 1; $x <= $count; $x++) {
$im->previousImage();
$tmpImageWidth = $im->getImageWidth();
$tmpImageHeight = $im->getImageHeight();
// ???
}
}
$im->writeImages($targetFile, true);
我想,我会找到一种可行的方法,但要反复试验。但是我想知道,是否有更简单的方法来实现这一目标。
TL; DR:我需要一种简单的方法,使用PHP-Imagick(不选择使用GD)将任何大小的ICO文件转换为16x16 px PNG。
更新:
我的解决方案(目前可以使用,但可能不是最佳选择):
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$count = $im->getNumberImages();
$targetWidth = $targetHeight = 16;
if ($count > 1) {
$images = [];
for ($x = 1; $x <= $count; $x++) {
$im->previousImage();
$images[] = [
'object' => $im,
'size' => $im->getImageWidth() + $im->getImageHeight()
];
}
$minSize = min(array_column($images, 'size'));
$image = array_values(array_filter($images, function($image) use ($minSize) {
return $minSize === $image['size'];
}))[0];
$im = $image['object'];
if ($image['size'] <> $targetWidth + $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
else {
if ($im->getImageWidth() <> $targetWidth || $im->getImageHeight() <> $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
$im->writeImage($targetFile);
答案 0 :(得分:1)
更新后的答案
在重新阅读您的问题时,似乎您实际上是想从ICO文件制作PNG文件。我已经读过Wikipedia entry for ICO files,并且像往常一样,它是闭源Microsoft资料中指定不当的复杂混乱。我无法确定它们是按某种顺序排列的。.最小的优先,或者最大的优先,所以我认为我的建议是按照您的计划简单地遍历ICO文件中的所有图像,并获得最大的图像。像素数并将其大小调整为16x16。
原始答案
太多评论了,也许还不足以回答...我完全没有使用PHP Imagick ,但是如果您在 ImageMagick 在终端的命令行中,您可以设置ICO大小,例如this:
in_header
说出要嵌入到输出文件中的分辨率。正如我说的,我不使用PHP,但是我相信等效的东西是这样的:
magick INPUT -define icon:auto-resize="256,128,96,64,16" output.ico
对不起,我无能为力,我只是没有设置使用PHP和 Imagick ,但希望您可以从这里解决问题。
答案 1 :(得分:0)
我的最终解决方案:
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$count = $im->getNumberImages();
$targetWidth = $targetHeight = 16;
if ($count > 1) {
$images = [];
for ($x = 1; $x <= $count; $x++) {
$im->previousImage();
$images[] = [
'object' => $im,
'size' => $im->getImageWidth() + $im->getImageHeight()
];
}
$minSize = min(array_column($images, 'size'));
$image = array_values(array_filter($images, function($image) use ($minSize) {
return $minSize === $image['size'];
}))[0];
$im = $image['object'];
if ($image['size'] <> $targetWidth + $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
else {
if ($im->getImageWidth() <> $targetWidth || $im->getImageHeight() <> $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
$im->writeImage($targetFile);