【问题标题】:Recipe for creating Windows ICO files with ImageMagick?使用 ImageMagick 创建 Windows ICO 文件的方法?
【发布时间】:2012-07-10 13:02:14
【问题描述】:

我想使用 ImageMagick 为我的 Windows 应用程序(从 SVG 文件)动态创建 .ico 图标。我该怎么做?

Microsoft lists various color depth and size requirements 用于图标。 ImageMagick 有-depth-colors 选项,但我不确定在这种情况下如何正确使用它们。

另外,看起来Vista+ supports 256x256 hi-res icon 嵌入到了相同的.ico 中,它可以(应该?必须?)是压缩的PNG。如何将 Windows XP 图标和这个新的 Vista 图标“加入”到一个 .ico 文件中?

【问题讨论】:

  • 如果您想知道,这是 应用程序 图标(粘贴在 .exe 本身上的那个)。
  • ImageMagick doesn't support 256x256 icons 会破坏这些文件

标签: icons imagemagick


【解决方案1】:

我一直在努力解决同样的问题。我有一个带有我的图标图像的 SVG,我需要从中创建一个 icon.ico 文件。让我描述一下我找到的解决方案:

第 1 步:确定要在 icon.ico 文件中包含哪些分辨率。

对此没有明确的指导方针。甚至微软也以不一致的图标分辨率发布其软件。有一个question 关于那个。 因此,我认为我们能做的最好的事情就是使用IconsExtract from Nirsoft 或类似的方法来检查最流行和最现代的 Windows 程序的图标中包含哪些分辨率。

第 2 步:为要包含在 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 文件渲染到每个分辨率中准确。

第 3 步:组装您的 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 用于解决以下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
}

【讨论】:

    【解决方案2】:

    从 SVG 创建 ICO 文件同时保持纵横比:

    1. 查找 SVG 比例(例如 1920x1080)
    2. 对于最大 256px 宽的图标,按比例:[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

    【讨论】:

      【解决方案3】:
      magick convert in.jpg -define icon:auto-resize=16,48,256 -compress zip out.ico
      

      http://imagemagick.org/script/command-line-options.php#define

      【讨论】:

      • 我也会将 32 和 64 添加到尺寸列表中 - 然后我认为这对于所有 Windows 操作系统来说都是完美的:s
      • 我没有注意到有或没有 '-compress zip' 的任何区别,虽然
      • “convert.im6: 宽度或高度超出限制” — 通过首先将输入图像的大小调整为 256 × 256 像素来修复。但是原始 png 中的透明部分变成了白色。
      【解决方案4】:

      在所有先前答案的基础上更正以下错误:

      • 不要使用-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 -z -e $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 
      

      【讨论】:

        【解决方案5】:

        Bash one-liner 将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's answer,但避免了显式循环和临时文件。

        stderr 和重定向是为了避免 Inkscape 在 stdout 上的成功消息(“位图另存为:/dev/stdout”)最终出现在图像数据中。

        【讨论】:

        • 完美的解决方案稍微复杂一点,因为需要提供 16、24、32、48 大小的 4 位、8 位和 32 位图像。
        【解决方案6】:

        我清理了 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
        

        【讨论】:

          【解决方案7】:

          这是来自FAQ 的标准配方,修改为具有msdn link 中提到的所有分辨率(除了“其他尺寸...”下的那些)(其他答案没有所需的所有分辨率)

           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
          

          【讨论】:

            【解决方案8】:

            修改 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 个图标,对吗?
            【解决方案9】:

            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 版本才需要这些图标) 如果你需要的话,应该可以做更多的工作让它来做这些。

            【讨论】:

            • 这可以在 512 像素分辨率下工作吗?我在其他地方看到 ImageMagick 不允许 512 ico 大小。我正在制作要在 4k 大屏幕上显示的图标,所以我认为以 512 分辨率以防万一是明智之举。
            • @DavidA.French 据我所知是的(基于我上面的几个修改后的答案还包含一个 512px ico);不过最好还是试试看吧?
            • 看来 mac 解决方案依赖于 tiff2ico 和 windows 解决方案,而设置 512 大小并不会实际生成 512 图标。无论如何感谢您的帮助!
            • @DavidA.French ImageMagick doesn't even work with 256x256 icon files。我试过了,很多输出文件都坏了
            • ImageMagick 可以用来代替inkscape,但是您需要以特定方式使用它才能获得与inkscape 相同的质量(详细信息在我的answer)。 @phuclv,ImageMagick 确实存在 256x256 图标的问题,但有一个解决方法。请查看我的answer了解更多详情
            【解决方案10】:

            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
            

            您可以根据需要对其进行修改以包含更大的分辨率,并更改边框、透明度设置等内容。

            【讨论】:

            • 事实上,如果你使用-alpha remove而不是-alpha off,你应该可以省略-bordercolor white -border 0
            • 除非作者想用 SVG 来做这件事。正如我在回答中指出的那样,在 SVG 上使用此命令将完全破坏生成图标的质量,因为 imagemagick 仅在光栅化后调整 SVG 的大小。
            • @MalcolmMacLeod 是的,你说的很对,使用这种方法直接从 SVG 转换会产生糟糕的结果
            • 从 SVG 转换我想知道您是否可以先“转换为大图像”(如 png),或者可能使用密度和调整大小过采样技巧:imagemagick.org/discourse-server/viewtopic.php?f=1&t=13585
            猜你喜欢
            • 1970-01-01
            • 2011-03-12
            • 1970-01-01
            • 2022-07-29
            • 2013-01-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多