使用ImageMagick创建Windows ICO文件的步骤?

33

我想通过使用ImageMagick从SVG文件动态创建Windows应用程序的.ico图标。请问我该如何操作?

Microsoft 列出了图标的各种颜色深度和大小要求。ImageMagick具有-depth-colors选项,但我不确定在这种情况下如何正确使用它们。

此外,似乎Vista+支持256x256高分辨率图标嵌入到同一个.ico中,可以(应该?必须?)是压缩的PNG格式。请问如何将Windows XP图标和这个新的Vista图标合并成单个.ico文件?


如果你想知道的话,这是应用程序图标(粘在.exe文件上的那个)。 - Linas Valiukas
ImageMagick不支持256x256图标,并且会破坏这些文件。 - phuclv
相关帖子:https://dev59.com/NXA75IYBdhLWcg3wi5sr#74392449 - Mahozad
10个回答

35
ImageMagick在他们的文档中有一个相关的解决方案,请参考FavIcon Web Page Link Thumbnail
基本上,你需要运行以下命令:
convert image.png  -bordercolor white -border 0 \
          \( -clone 0 -resize 16x16 \) \
          \( -clone 0 -resize 32x32 \) \
          \( -clone 0 -resize 48x48 \) \
          \( -clone 0 -resize 64x64 \) \
          -delete 0 -alpha off -colors 256 favicon.ico

你可以根据需要修改此内容,包括更大的分辨率以及更改边框、透明度设置等。

5
实际上,如果您使用-alpha remove而不是-alpha off,则应该能够省略-bordercolor white -border 0 - sschuberth
2
除非作者想使用SVG进行操作。正如我在回答中指出的那样,对SVG使用此命令将完全破坏生成图标的质量,因为imagemagick只会在光栅化后调整SVG的大小。 - Malcolm MacLeod
@MalcolmMacLeod 是的,你说得很对,使用这种方法直接从SVG转换会产生糟糕的结果。 - RobV
4
我想知道在将SVG转换时是否可以先“转换为大图像”(如png),或者可能使用密度和调整过采样的技巧:http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=13585 - rogerdpack

10

2
我会将32位和64位也添加到大小列表中 - 然后我认为这对于所有Windows操作系统都是完美的。 - Jouni Aro
1
我没有注意到是否使用“-compress zip”有任何区别。 - Jouni Aro
“convert.im6: width or height exceeds limit” — 通过将输入图像首先调整为256×256像素来解决。但原始PNG中的透明部分变成了白色。 - Smylers

10

似乎仅仅使用ImageMagick是无法达到此目的的,因为它不能很好地处理SVG调整大小(而是在光栅化之后才调整SVG,这会产生可怕的结果)。

通过使用Inkscape进行转换似乎是可能的,例如,下面的一行命令应该可以给你一个可用的图标,并包含所有图标尺寸:

mkdir temp; declare -a res=(16 24 32 48 64 128 256); for f in *.svg; do for r in "${res[@]}"; do inkscape -z -e temp/${f}${r}.png -w $r -h $r $f; done; resm=( "${res[@]/#/temp/$f}" ); resm=( "${resm[@]/%/.png}" ); convert "${resm[@]}" ${f%%.*}.ico; done; rm -rf temp;

上述方法不会为您提供文件中的8位和4位图标(我认为这些仅适用于不再受支持的旧Windows版本) 如果需要,通过更多的工作应该可以实现它们。

1
这个能在512像素的分辨率下工作吗?我在其他地方看到ImageMagick不支持512像素的ico尺寸。我正在制作将要放在大型4k屏幕上的图标,所以我认为最好还是有一个512像素的分辨率备用。 - Aslan French
据我所知,是的(基于我的答案修改的几个答案也包含512px ico); 但最好还是试一试看看? - Malcolm MacLeod
似乎Mac解决方案依赖于tiff2ico,而在Windows上设置512大小并不会实际生成512图标。无论如何,感谢您的帮助! - Aslan French
1
@DavidA.French ImageMagick甚至无法处理256x256图标文件。我尝试了很多次,但输出的文件很多都损坏了。 - phuclv
1
ImageMagick可以代替Inkscape使用,但需要以特定方式使用才能获得与Inkscape相同的质量(具体细节请参见我的回答)。@phuclv,ImageMagick确实存在256x256图标的问题,但有一个解决方法。请查看我的回答以获取更多详细信息。 - PolarBear
显示剩余2条评论

9

我整理了Malcolm的解决方案,修复了一个错误,并使脚本输出tiff文件,这样你就可以在OSX上运行tiff2icns。

#! /bin/bash
# converts the passed-in svgs to tiff and ico

if [[ $# -eq 0 ]]; then
    echo "Usage: $0 svg1 [svg2 [...]]"
    exit 0
fi

temp=$(mktemp -d)
declare -a res=(16 24 32 48 64 128 256 512)
for f in $*; do
    mkdir -p $temp/$(dirname $f)
    for r in "${res[@]}"; do
        inkscape -z -e $temp/${f}${r}.png -w $r -h $r $f
    done
    resm=( "${res[@]/#/$temp/$f}" )
    resm=( "${resm[@]/%/.png}" )
    for filetype in ico tiff; do
        convert "${resm[@]}" ${f%%.*}.$filetype
    done
done
rm -rf $temp

6
我一直在努力解决同样的问题。我有一个带有图标的SVG文件,我需要从中创建一个icon.ico文件。让我描述一下我找到的解决方案:
第一步:确定要包含在icon.ico文件中的分辨率。
关于这个问题没有明确的指导方针。即使是微软也会以不一致的图标分辨率发布其软件。关于这个问题有一个问题。 因此,我认为我们能做的最好的事情就是使用Nirsoft的IconsExtract工具。通过这个工具,你可以检查流行的现代Windows程序中包含的分辨率。
第二步:为您想要包含在icon.ico文件中的每个分辨率创建.png文件。
很多答案建议使用Inkscape,但你可以用以下方法使用ImageMagick来完成所有操作(以防万一,我已经检查过结果图像与使用inkscape时的相同):
magick.exe convert -size 16x16 -background transparent -depth 8 MyIconImage.svg 16.png
...
magick.exe convert -size 256x256 -background transparent -depth 8 MyIconImage.svg 256.png

然而,如果你仍然想要使用Inkscape,这是命令:
inkscape.exe MyIconImage.svg -w 16 -h 16 -o 16.png

一些答案还建议使用ImageMagick的icon:auto-resize命令行参数,以避免为每个分辨率创建单独的PNG文件。我不建议使用它,因为为了获得最佳质量,最好避免调整大小,因为这比将SVG文件渲染到每个分辨率中要不准确。
第三步:组装您的icon.ico文件。
magick.exe convert 16.png 20.png 24.png 32.png 40.png 48.png 64.png 256.png -compress jpeg icon.ico

-compress jpeg被用作解决ImageMagick中特定问题的一种变通方法,具体描述请参考以下issue in ImageMagick链接所述的comment
您可以使用以下命令查看创建的icon.ico文件的详细信息:

magick.exe identify icon.ico

Powershell脚本"CreateIcoFromSvg.ps1"

让我提供一个自动化上述步骤的Powershell脚本:

# You can download ImageMagick from: https://imagemagick.org/script/download.php
$imageMagick = "$PSScriptRoot/ImageMagick-7.1.0-portable-Q16-x64/magick.exe"

$svgIcon = "MySvgIcon.svg"
$iconResolutions = 16,20,24,32,40,48,64,256

# Create 16.png, ..., 256.png image files
$pngImages = @()
Foreach($r in $iconResolutions) {
    & $imageMagick convert -size "${r}x${r}" -background transparent -depth 8 $svgIcon "${r}.png"
    $pngImages += "${r}.png"
}

# Combine all PNG image files into an icon.ico file
& $imageMagick convert $pngImages -compress jpeg "icon.ico"

# Remove PNG files
Foreach($image in $pngImages) {
    Remove-Item $image
}

感谢您抽出时间并附上PS脚本。唯一缺少的是没有反锯齿处理,因此大小看起来太粗糙了。 - user1908746

4

2022年更新

我最近意识到,使用convert实际上无法解决此任务,因为convert会将所有输入图像转换为bmp并更改图像的颜色深度。

因此,我已更新我的脚本以使用icotoolsudo apt install icoutils):

#!/bin/bash

for size in 16 24 32 48 64 96 128 256; do
    inkscape --export-filename $size.png -w $size -h $size logo.svg >/dev/null 2>/dev/null
done

for size in 16 24 32 48; do

  convert -colors 256 +dither $size.png png8:$size-8.png
  convert -colors 16  +dither $size-8.png $size-4.png

done

convert 16.png 24.png 32.png 48.png 16-8.png 24-8.png 32-8.png 48-8.png 16-4.png 24-4.png 32-4.png 48-4.png 64.png 96.png 128.png 256.png logo.ico

icotool -c -o logo.ico 16.png 24.png 32.png 48.png 16-8.png 24-8.png 32-8.png 48-8.png 16-4.png 24-4.png 32-4.png 48-4.png 64.png 96.png -r 128.png -r 256.png

rm 16.png 24.png 32.png 48.png 16-8.png 24-8.png 32-8.png 48-8.png 16-4.png 24-4.png 32-4.png 48-4.png 64.png 96.png 128.png 256.png

原始答案

在之前所有的回答基础上,纠正以下错误:

  • 不要使用-color=256,因为现代Windows版本(Vista+)需要所有尺寸的32位颜色版本。
  • Windows中必需的尺寸为16、24、32、48、64、128、256。大多数脚本都忘记了这些。我不确定96是否真的需要,但它没有坏处。
  • 您需要为尺寸16、24、32和48包括4位和8位调色板版本(显然是为了特别支持远程桌面应用程序)。

所有内容都在一个bash脚本中(从logo.svg开始生成logo.ico):

#!/bin/bash

for size in 16 24 32 48 64 96 128 256; do
    inkscape --export-filename $size.png -w $size -h $size logo.svg >/dev/null 2>/dev/null
done

for size in 16 24 32 48; do

  convert -colors 256 +dither $size.png png8:$size-8.png
  convert -colors 16  +dither $size-8.png $size-4.png

done

convert 16.png 24.png 32.png 48.png 16-8.png 24-8.png 32-8.png 48-8.png 16-4.png 24-4.png 32-4.png 48-4.png 64.png 96.png 128.png 256.png logo.ico

rm 16.png 24.png 32.png 48.png 16-8.png 24-8.png 32-8.png 48-8.png 16-4.png 24-4.png 32-4.png 48-4.png 64.png 96.png 128.png 256.png 

4
这是从FAQ中标准的配方,经过修改以包含msdn link中提到的所有分辨率(除了“其他尺寸…”下面的那些)(另一个答案没有所有所需的分辨率)。请保留HTML标签。
 convert input.png -bordercolor white -border 0 ( -clone 0 -resize 16x16 ) ( -clone 0 -resize 24x24 ) ( -clone 0 -resize 32x32 ) ( -clone 0 -resize 40x40 ) ( -clone 0 -resize 48x48 ) ( -clone 0 -resize 64x64 ) ( -clone 0 -resize 256x256 ) -delete 0 -alpha off -colors 256 output.ico

2
用 Bash 一行命令将 logo.svg 转换为 logo.ico,使用 Inkscape 导出不同大小的 png 图像:
eval convert \
  '<(inkscape -e /dev/stderr logo.svg -w '{16,24,32,48,64,128,256}' 2>&1 > /dev/null)' \
  logo.ico

受Malcolm MacLeod答案的启发,但避免了显式循环和临时文件。
使用stderr和重定向是为了避免Inkscape的成功消息出现在图像数据中,该消息会在stdout上显示为“Bitmap saved as: /dev/stdout”。

一个完美的解决方案会稍微复杂一些,因为需要提供16、24、32、48尺寸的图像,并且这些图像需要以4位、8位和32位的格式呈现。 - Christopher Oezbek

1

修改hnasarat的答案,适用于Windows用户。最简单的方法是使用Chocolatey安装InkScape和ImageMagick,然后在批处理文件中运行以下命令。 (它不像其他答案那样灵活,你只需传入一个svg文件,但它会生成Favicon Cheat Sheet中推荐的所有网站图标。)

@ECHO off

IF "%1"=="" (
    ECHO You must provide an svg file
    EXIT /b
) 

IF NOT EXIST favicons MD favicons

SET "sizes=16 24 32 48 57 64 72 96 120 128 144 152 195 228 256 512"

FOR %%s IN (%sizes%) DO (
    inkscape -z -e favicons/favicon-%%s.png -w %%s -h %%s %1
)

convert favicons/favicon-16.png favicons/favicon-24.png favicons/favicon-32.png favicons/favicon-48.png favicons/favicon-64.png favicons/favicon.ico

嗨,根据我所读的,Imagick 不能生成512个图标,对吗? - Aslan French

0

创建 ICO 文件并保持 SVG 的纵横比:

  1. 查找 SVG 的比例(例如 1920x1080)
  2. 对于最大宽度为 256 像素的图标,进行比例计算:[1920:1080=256:x] -> x=(1080*256)/1920=144
  3. 最后,使用 ImageMagick 的 convert 命令:

    convert -background none -resize 256x144 -gravity center -extent 256x144 image.svg image.ico


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接