【问题标题】:Convert ICO to PNG using PHP Imagick使用 PHP Imagick 将 ICO 转换为 PNG
【发布时间】:2020-04-25 14:01:05
【问题描述】:

我目前正在尝试使用 PHP-Imagick 将 ICO 文件转换为 16x16 像素的 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 文件

  • favicon-0.png
  • favicon-1.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:我需要一种简单的方法来将任意大小的 ICO 文件转换为 16x16 像素的 PNG,使用 PHP-Imagick(不能使用 GD)。

更新:

我的(目前有效,但可能不是最理想的)解决方案:

<?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);

【问题讨论】:

  • 看起来你有一个可行的解决方案,干得好!将其作为答案并接受它为正确的并获得积分!

标签: php imagemagick imagick ico


【解决方案1】:

更新答案

在重新阅读您的问题时,您似乎真的想从 ICO 文件制作 PNG 文件。我已经阅读了Wikipedia entry for ICO files,并且像往常一样,它是一个指定不清的复杂的闭源微软东西。我不知道它们是否按某种顺序排列.. 最小在前,还是最大在前,所以我认为我的建议是按照您的计划简单地遍历 ICO 文件中的所有图像,并获得最大的图像像素数并将其调整为 16x16。

原答案

太多的评论,也许不足以回答...我根本不使用 PHP Imagick,但如果你使用 ImageMagick 在在终端命令行中,您可以设置 ICO 大小,如 this:

magick INPUT -define icon:auto-resize="256,128,96,64,16" output.ico

说明您希望在输出文件中嵌入什么分辨率。正如我所说,我不使用 PHP,但我相信相当于:

$imagick->setOption('icon:auto-resize', "16");

抱歉,我帮不上忙,我只是没有准备好使用 PHP 和 Imagick,但希望您能从这里解决问题。

【讨论】:

  • 感谢您的回答。我刚刚更新了我的问题并添加了当前适用于我的解决方案。我还没有测试所有案例,但至少我的测试 ICO 文件将被转换为(单个)16x16 像素 PNG。
【解决方案2】:

我的最终解决方案:

<?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);

【讨论】:

    猜你喜欢
    • 2017-07-26
    • 2011-07-19
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 2011-06-05
    • 2017-06-11
    相关资源
    最近更新 更多