如何使用 iconutil 手动创建 icns 文件?

当我验证我的应用程序时,我得到这个错误:

捆绑不包含 ICNS 格式的图标,同时包含 512x512512x512@2x图像。

我用 Img2icns应用程序来制作 icns 图标,直到今天它都能正常工作。但现在我得到了这个错误,而且没有办法让它工作。我尝试将两个 PNG 文件(512x5121024x1024)放在 Img2icns中,但我总是得到这个错误。我也试图遵循苹果 OS X 人机界面指南中的说明,但当我试图制作图标集时,我得到了这个终端错误:

- bash: 意外标记‘ newline’附近的语法错误

我不太擅长使用终端命令,所以可能我做错了什么。我写道:

iconutil -c icns </Users/myname/SDK Mac Apps/MyApp/grafica/icon.iconset>

如果有人能帮忙,我将不胜感激。谢谢,马西。

115331 次浏览

核对下列指示(链接) :

使用 iconutil 手动创建 icns 文件

iconutil命令行工具将 iconset文件夹转换为可部署的高分辨率 icns 文件。(您可以通过在 Terminal 中输入 man iconutil来查找此工具的完整文档。)使用这个工具还可以压缩产生的 icns文件,因此不需要执行额外的压缩。

将一组图标转换为 icns 文件

在“终端”窗口中输入以下命令:

iconutil -c icns <iconset filename>

其中 <iconset filename>是包含要转换为 icns的图标集的文件夹的路径。输出被写入到与 iconset file相同的位置,除非您指定如下所示的输出文件:

iconutil -c icns -o <icon filename> <iconset filename>

换句话说,您需要将 <iconset filename>替换为:

/Users/myname/SDK Mac Apps/MyApp/grafica/icon.iconset

因为路径包含空格,所以需要使用双引号,例如:

iconutil -c icns "/Users/myname/SDK Mac Apps/MyApp/grafica/icon.iconset"

这个命令应该可以正常工作。

当我验证我的应用程序时,我得到这个错误:

捆绑不包含 ICNS 格式的图标,即同时包含512x512和512x512@2x 图像。

Something

我不太擅长终端命令,所以可能我做错了什么,我写道:

iconutil -c icns </Users/myname/SDK Mac Apps/MyApp/grafica/icon.iconset>

首先,正如我在评论 Anne 的回答时提到的,你可能不需要使用 iconutil。您应该能够将图标集添加到项目中,并让 Xcode 将其作为构建的一部分进行转换。

不管怎样,这可能是你的问题:

我尝试把两个 PNG 文件(512x512和1024x1024)放在一起... 但我总是得到错误。

没有1024乘以1024的点大小

PNG 文件的名称必须适当: icon _ 512x512@2x.PNG

这些命令(在终端中输入)帮助我将一个旧的 icns 文件转换成新的格式:

cd Folder_With_Icns_File
iconutil -c iconset Your_Icon_Name.icns
rm Your_Icon_Name.icns
iconutil -c icns Your_Icon_Name.iconset
rm -R Your_Icon_Name.iconset

更新

不再支持 iconutil 的 -c参数。改为使用 --convert:

cd Folder_With_Icns_File
iconutil --convert iconset Your_Icon_Name.icns
rm Your_Icon_Name.icns
iconutil --convert icns Your_Icon_Name.iconset
rm -R Your_Icon_Name.iconset

苹果早期的 Icon Composer 2.2版本运行良好,只需打开。ICNS 在其中,按1024x1024按钮,并添加您的图像。

下面是将1024x1024png (名为“ Icon1024.png”)转换为所需 icns 文件的脚本。将它保存到一个名为“ CreateICNS.src”的文件夹中,你的 png 文件位于同一个文件夹的终端“ cd”中,然后键入“ source CreateICNS.src”调用它:

mkdir MyIcon.iconset
sips -z 16 16     Icon1024.png --out MyIcon.iconset/icon_16x16.png
sips -z 32 32     Icon1024.png --out MyIcon.iconset/icon_16x16@2x.png
sips -z 32 32     Icon1024.png --out MyIcon.iconset/icon_32x32.png
sips -z 64 64     Icon1024.png --out MyIcon.iconset/icon_32x32@2x.png
sips -z 128 128   Icon1024.png --out MyIcon.iconset/icon_128x128.png
sips -z 256 256   Icon1024.png --out MyIcon.iconset/icon_128x128@2x.png
sips -z 256 256   Icon1024.png --out MyIcon.iconset/icon_256x256.png
sips -z 512 512   Icon1024.png --out MyIcon.iconset/icon_256x256@2x.png
sips -z 512 512   Icon1024.png --out MyIcon.iconset/icon_512x512.png
cp Icon1024.png MyIcon.iconset/icon_512x512@2x.png
iconutil -c icns MyIcon.iconset
rm -R MyIcon.iconset

我重写了“亨利”的剧本,让它看起来更好:

#!/bin/zsh
NAME=$(basename $1 .png); DIR="$NAME.iconset"
mkdir -pv $DIR
for m r in 'n' '' '((n+1))' '@2x'; do
for n in $(seq 4 9 | grep -v 6); do
p=$((2**$m)); q=$((2**$n))
OUT="$DIR/icon_${q}x${q}${r}.png"
sips -z $p $p $1 --out $OUT
done
done
iconutil -c icns $DIR
rm -frv $DIR

更新

不再支持 iconutil 的 -c参数。改为使用 -—convert:

#!/bin/zsh
NAME=$(basename $1 .png); DIR="$NAME.iconset"
mkdir -pv $DIR
for m r in 'n' '' '((n+1))' '@2x'; do
for n in $(seq 4 9 | grep -v 6); do
p=$((2**$m)); q=$((2**$n))
OUT="$DIR/icon_${q}x${q}${r}.png"
sips -z $p $p $1 --out $OUT
done
done
iconutil -—convert icns $DIR
rm -frv $DIR

附加注释,当您创建 . icns 文件中,需要将所有图片文件重命名为前缀“ icon _时“ ,否则,iconutil 将失败并出现错误消息:”。Error: 未能生成 ICNS一点信息都没有。

有一个命令行节点模块,可以完成将 PNG 文件转换为图标集目录的所有工作:

npm install -g node-icns
nicns --in adventure-cat.png --out adventure-cat.icns

尽管使用各种脚本将高分辨率的 PNG图像转换成不同的低分辨率拷贝看起来很方便(事实也的确如此) ,但是不要忘记这种自动调整大小的方法将呈现 明显不完美的图像

分辨率降低ーー图标模糊化!

我的意思是,我也喜欢 imagemagick,但它不是这个任务的正确工具!

相反,您应该始终以某种矢量格式从设计器请求徽标,例如在 SVG中。有了这个,你可以手动准备完美的 PNG文件在所有需要的分辨率,然后使一个单一的 .icns文件,这将使你的应用程序图标看起来美丽的每一个单一的屏幕上,从廉价的 iPhone SE 到一些最新的 iMac 的高端 Retina 显示器。你可以使用 Photoshop,GIMP 或任何其他你选择的工具来生成这些 PNG。

从2020年的最新 苹果的人机界面指南开始,你应该准备以下 PNG文件:

+---------------------+--------------------+--------------+
|      filename       | resolution, pixels | density, PPI |
+---------------------+--------------------+--------------+
| icon_16x16.png      | 16x16              |           72 |
| icon_16x16@2x.png   | 32x32              |          144 |
| icon_32x32.png      | 32x32              |           72 |
| icon_32x32@2x.png   | 64x64              |          144 |
| icon_128x128.png    | 128x128            |           72 |
| icon_128x128@2x.png | 256x256            |          144 |
| icon_256x256.png    | 256x256            |           72 |
| icon_256x256@2x.png | 512x512            |          144 |
| icon_512x512.png    | 512x512            |           72 |
| icon_512x512@2x.png | 1024x1024          |          144 |
+---------------------+--------------------+--------------+

准备好所有 PNG 文件后,将它们放入某个扩展名为 .iconset的目录(例如 Logos.iconset) ,然后从 Terminal执行以下操作:

iconutil --convert icns Logos.iconset

如果在执行这个命令之后没有错误,那么所有的文件都被正确地处理了,并且你在同一个目录中得到了 Logos.icns文件,其中包含了适合任何现代屏幕的应用程序的所有漂亮清晰的标志。

你好,为了满足我的需要,我制作了一个可以单独拖放图标或在文件夹中搜索图标的小液滴(我限制在文件夹中搜索所有图标的卷需要很长时间)。因此,在拖放过程中,你可以拖放文件夹或应用程序,任何可以包含图标的东西。创建的图标集包含原始图标的名称,它被放置在目录“/aaaicones”和图标的路径中。文件夹中的示例“/aaaicones,如果您提交 xcode.app,您将发现 “/aaaicones/Applications/xcode.app/acc.iconset”和/aaaicones/Applications/xcode.app/acc.icns (重新创建的图标)将会有一个文本文件,其中会跟踪图标的完整路径,以及相应图标集示例的路径 应用程序/xcode.app/内容/应用程序/Instruments.app/内容/框架/InstrumentsPlugIn.Framework/版本/A/Resources/access.icns “/aaaicones/Applications/xcode.app/accs.iconset”在示例中(xcode)这可以创建一个大小为214MB 的文件夹(包含所有图标和图标集)。如果您只处理一个图标,那么它将被放置在目录“/aaaicones/alconeseule/”及其原始路径中,例如 /aaaicones/alconeseule/Mac Elcapan/. VolumeIcon.icns 和/aaaicones/alconeseule/Mac Elcapan/. VolumeIcon.iconset with/aaaicones/alconeseule/Mac Elcapan/aalisticones.txt 液滴在

下面
on open draggedItems
set input to draggedItems
set fich to draggedItems




set media to {}


set theInfo to {}


set n to "0"
repeat with currentItem in draggedItems
set dirchoisi to POSIX path of fich
if ".icns" is not in dirchoisi then
if "Volumes" is not in dirchoisi then


set origi to do shell script "echo   /aaaicones" & dirchoisi
set fich to do shell script "echo " & fich & " | xxd -p -c 100000 | sed 's#3a#2f#g' | xxd -r -p | sed 's#" & dirchoisi & "#" & "/aaaicones" & dirchoisi & "#g' | xxd -p -c 100000 | sed 's#2f#3a#g' | xxd -r -p"
tell application "Finder"
if exists (folder fich) then
set nn to "0"
repeat with nn from 1 to 5
set origi to do shell script "echo  " & origi & "/" & " | sed 's#//#" & nn & "/" & "#'"
set fich to do shell script "echo " & fich & " | sed 's#:aaaicones*.*#" & origi & "#'" & " | xxd -p -c 100000 | sed 's#2f#3a#g' | xxd -r -p"


if not (exists folder (fich as Unicode text)) then
try
set origi to do shell script "echo  " & origi
exit repeat
end try
end if
end repeat
end if
end tell
tell application "Finder"
if not (exists folder (fich as Unicode text)) then
do shell script "mkdir -p -m 0777 " & quoted form of origi
end if
end tell
try
set theInfo to do shell script "find " & (quoted form of dirchoisi) & " -name *.icns "
end try








set AppleScript's text item delimiters to return


set theList to text items of theInfo


set AppleScript's text item delimiters to ""


set n to count theList
repeat with i from 1 to n
if "Volumes" is not in item i of theList then
set end of media to item i of theList
end if
end repeat
set n to count media
set cheminicns to do shell script " > " & quoted form of (origi & "aalisticones.txt") & " |  chmod 777 " & quoted form of (origi & "aalisticones.txt")
set cheminicns to do shell script "ls " & quoted form of (origi & "aalisticones.txt")


tell application "Finder"
set letext to (POSIX file cheminicns as alias)
set label index of letext to 2
end tell






repeat with i from 1 to n


set hdd to item i of media
try


set input to do shell script "echo   " & hdd & " | sed 's#//#/#g; s#(#\\(#g;s#)#\\)#g' "
do shell script "echo   " & quoted form of input & " >>" & quoted form of cheminicns
set png to do shell script "echo " & quoted form of input & " | sed 's#.*/##' "


do shell script "cp -f " & quoted form of input & " " & quoted form of origi
set input to do shell script "iconutil -c iconset  " & quoted form of (origi & png)
do shell script "echo   " & quoted form of (origi & png) & " | sed 's#.icns#.iconset#' >>" & quoted form of cheminicns
end try
end repeat
tell application "Finder"
if exists (folder fich) then
open fich
end if
end tell


end if
else


set input to do shell script "echo   " & dirchoisi & " | sed 's#//#/#g; s#(#\\(#g;s#)#\\)#g' "
set png to do shell script "echo " & quoted form of input & " | sed 's#.*/##' "
set origi to do shell script "echo " & quoted form of ("/aaaicones/aIconeseule/" & input) & " | sed 's#/Volumes/##; s#" & quoted form of png & "##'"
do shell script "mkdir -p -m 0777 " & quoted form of origi
do shell script "echo   " & quoted form of input & " >>" & quoted form of origi & "aalisticones.txt"


do shell script "cp -f " & quoted form of input & " " & quoted form of origi
set input to do shell script "iconutil -c iconset  " & quoted form of (origi & png)
do shell script "echo   " & quoted form of (origi & png) & " >>" & quoted form of origi & "aalisticones.txt"
end if
end repeat
end open

我已经编写了一个 bash 脚本,用于从 svg 文件生成 icns:

#!/usr/bin/env bash
sizes=(16 32 64 128 256 512)
largfile='icon_512x512@2x.png'
if [ ! -f "$largfile" ]; then
convert -background none -resize 1024x1024 "$1" "$largfile"
fi
for s in "${sizes[@]}"; do
echo $s
convert -background none -resize ${s}x${s} "$largfile" "icon_${s}x$s.png"
done


cp 'icon_32x32.png'     'icon_16x16@2x.png'
mv 'icon_64x64.png'     'icon_32x32@2x.png'
cp 'icon_256x256.png'   'icon_128x128@2x.png'
cp 'icon_512x512.png'   'icon_256x256@2x.png'


mkdir icon.iconset
mv icon_*x*.png icon.iconset
iconutil -c icns icon.iconset

确保在 Mac 上已经安装了图像管理器,并且支持 library svg:

brew install imagemagick --with-librsvg

这个剧本对我很有用。


更新

为了更彻底地处理这个问题,我创建了一个命令行工具(用 Swift 编写) ,用于生成具有正确布局和格式的 AppIcon.appiconset:

Https://github.com/kindlychung/genicon

下面是一个主要基于 亨利的例子的函数(在 ~/.bash_profile中可能很有用) :

mkicns() {
if [[ -z "$*" ]] || [[ "${*##*.}" != "png" ]]; then
echo "Input file invalid"
else
filename="${1%.*}"
mkdir "$filename".iconset
for i in 16 32 128 256 ; do
n=$(( i * 2 ))
sips -z $i $i "$1" --out "$filename".iconset/icon_${i}x${i}.png
sips -z $n $n "$1" --out "$filename".iconset/icon_${i}x${i}@2x.png
[[ $n -eq 512 ]] && \
sips -z $n $n "$1" --out "$filename".iconset/icon_${n}x${n}.png
(( i++ ))
done
cp "$1" "$filename".iconset/icon_512x512@2x.png
iconutil -c icns "$filename".iconset
rm -r "$filename".iconset
fi
}

用法 :

$ mkicns "filename.png"  # double-quote if spaces exist in filename

创建从 16x16512x512@2x的10个大小; 在 只有 .png格式。

@ dardo82的外壳代码很好。 这里有一个更简单的 sh 语言(针对所有 * nix 语言)和更快的语言(就像它真的很重要一样) :

#!/bin/sh
#   This runs silent, be as verbose as you wish
NAME=$(basename ${1} .png)
DIR="${NAME}.iconset"
mkdir -p ${DIR}
for i in 16 32 128 256 512 ; do
x=""
for p in $i $(($i+$i)) ; do
sips -z $p $p ${1} --out "${NAME}.iconset/icon_${i}x${i}${x}.png"
x="@2x"
done
done >/dev/null  # /dev/null in lieu of a "-s" silent option
iconutil -—convert icns $DIR
rm -r $DIR

运行 iconutil -c icns Icon.iconset

注意

  • Iconset 是一个文件夹
  • 名称以小写字母 icon_开头
  • 当你看到 Icon.icns与正确的图像,你知道它的工作

enter image description here

有两项任务:
- 创建10个正确的 icns 文件
- 让你的 Xcode 项目正确使用它们

由于这两个任务我都遇到了长达一小时的问题,而且我也不喜欢看不到正在发生的事情,这里有一条小心谨慎的方法:

创建10个正确的 icns 文件:
我使用了 Henry 上面的脚本: 它仍然适用于 HighSierra 和 Xcode 9.2,包括‘ c’命令。
我得到的 icns 文件在 Finder/Quicklook 中只显示了一个图标大小,在 Preview 中只显示了10个大小中的8个。
所以我使用终端,用 cd 到我的文件夹,并使用命令: iconutil-c 图标集(icns 文件名)在刚刚创建的 icns 文件恢复 icns 文件回到一个图标集文件夹,并且-瞧瞧-我可以看到我新创建的10个图标文件。使用快速查看图标集文件夹(并使用全屏模式,以便能够通过滑块缩放它们) ,我可以检查所有的尺寸实际上看起来非常好。

顺便说一句: 它们看起来比我在 PSE 中调整大小的尝试要好,很可能是因为我没有花时间去处理 PSE 中的所有调整大小的选项。如果您使用 PSE,请确保您的 png 文件保存没有颜色配置文件。另外,承认我的无知,对我来说,256x256@2文件和512x512文件是一样的——都是72dpi。试图遵循上面的144 dpi 评论对我没有用。

让您的 Xcode 项目正确使用它们:
首先,我删除了在 Xcode 的所有徒劳的尝试,并在 git 存储库中提交了一个干净的版本(在我疯狂地开始添加图标之前,最聪明的做法是先提交一个干净的版本)。
我还确保在 info.plist 文件中没有链接到“图标文件”条目的指针,并且在我的常规项目设置中,我已经为应用程序图标选择了 AppIcon。
然后,我添加了一个 assets.asset 目录,并在该目录中为 OS 添加了一个新的“ AppIcon and Launch Images”AppIcon 文件夹。
然后,我从图标集文件夹中将每个 png 图片文件复制(拖放并按下选项)到各自的 AppIcon Spaceholder 中。所以,我又一次看到了正在发生的事情。Xcode 确实将它转换成了 icns 文件,或者也许——作为我从 icns 文件夹派生出来的图标集文件夹——文件格式被接受了。

然后进行归档和验证,上传或验证时不会出现错误。

与@Henry (上面的注释)相同,但是以 PNG 文件名作为参数,并输出具有相同名称的 ICNS。

注意: PNG 文件名应该只有1个单独的扩展名,即 xpto.PNG。

(更新为 shell 脚本)

因此,将下面的代码保存到 png 文件所在的文件夹中名为“ CreateICNS.sh”的文件中,并给予其执行权限。

密码:

#!/bin/bash
IFS='.' read -ra ADDR <<< "$1"
ICONSET=${ADDR[0]}.iconset
mkdir $ICONSET
sips -z 16 16     $1 --out $ICONSET/icon_16x16.png
sips -z 32 32     $1 --out $ICONSET/icon_16x16@2x.png
sips -z 32 32     $1 --out $ICONSET/icon_32x32.png
sips -z 64 64     $1 --out $ICONSET/icon_32x32@2x.png
sips -z 128 128   $1 --out $ICONSET/icon_128x128.png
sips -z 256 256   $1 --out $ICONSET/icon_128x128@2x.png
sips -z 256 256   $1 --out $ICONSET/icon_256x256.png
sips -z 512 512   $1 --out $ICONSET/icon_256x256@2x.png
sips -z 512 512   $1 --out $ICONSET/icon_512x512.png
cp $1 $ICONSET/icon_512x512@2x.png
iconutil -c icns $ICONSET
rm -R $ICONSET

使用方法:

然后在终端中,“ cd”到同一个文件夹并键入:

./CreateICNS.sh {PNG filename}

其中{ PNG filename }是 PNG 文件的名称,即 xpto.PNG。

如果您的文件将被命名为 abc.png,您将使用:

./CreateICNS.sh abc.png

更新日期2021-05-20:

我有一个更新的版本,但我不知道我在哪里找到它离开这里的正确参考,所以如果有人是这个网页的所有者或知道一个链接在某个互联网页面,请评论,所以我可以更新演职员表:

这是一个完整的 bash 脚本,因此您应该将其保存为例如 png2icns.sh,并给予其执行权限。

然后您可以调用 png2icns.sh pngfile1.png,它将生成 ICNS 文件以及包含16x16和512x512之间的所有图标分辨率的图标集文件夹。

#!/bin/bash
# Creates an icns file from a source image


src_image="$1"
if [ -z "$1" ]; then
echo "No source image was passed to this script"
exit 1
fi


icns_name="$2"
if [ -z "$2" ]; then
icns_name="iconbuilder"
fi


if [ "${src_image:(-3)}" != "png" ]; then
echo "Source image is not a PNG, making a converted copy..."
/usr/bin/sips -s format png "$src_image" --out "${src_image}.png"
if [ $? -ne 0 ]; then
echo "The source image could not be converted to PNG format."
exit 1
fi
src_image="${src_image}.png"
fi


iconset_path="./${icns_name}.iconset"
if [ -e "$iconset_path" ]; then
/bin/rm -r "$iconset_path"
if [ $? -ne 0 ]; then
echo "There is a pre-existing file/dir $iconset_path the could not be deleted"
exit 1
fi
fi


/bin/mkdir "$iconset_path"


icon_file_list=(
"icon_16x16.png"
"icon_16x16@2x.png"
"icon_32x32.png"
"icon_32x32@2x.png"
"icon_128x128.png"
"icon_128x128@2x.png"
"icon_256x256.png"
"icon_256x256@2x.png"
"icon_512x512.png"
"icon_512x512@2x.png"
)


icon_size=(
'16'
'32'
'32'
'64'
'128'
'256'
'256'
'512'
'512'
'1024'
)


counter=0
for a in ${icon_file_list[@]}; do
icon="${iconset_path}/${a}"
/bin/cp "$src_image" "$icon"
icon_size=${icon_size[$counter]}
/usr/bin/sips -z $icon_size $icon_size "$icon"
counter=$(($counter + 1))
done


echo "Creating .icns file from $iconset_path"
/usr/bin/iconutil -c icns "$iconset_path"
if [ $? -ne 0 ]; then
echo "There was an error creating the .icns file"
exit 1
fi


echo "Done"
exit 0

我需要这个,但是为了 CMake。我还想给它一个 SVG 选项。

这是要点: https://gist.github.com/Qix-/f4090181e55ea365633da8c3d0ab5249

还有 CMake 代码:

# LICENSE: CC0 - go nuts.


# Hi :) This is what I used to generate the ICNS for my game, Tide.
# Both input formats (SVG vs PNG) work just fine, but in my experience
# the SVG came out with noticeably better results (although PNG wasn't
# a catastrophe either). The logo for the game was simple enough that
# SVG was indeed an option.


# To use:
#
#    make_icns( INPUT "path/to/img.{svg,png}"
#               OUTPUT ICNS_PATH )
#
# Then add it as a custom target or use it as a
# dependency somewhere - I give you that option.
#
# For example:
#
#    add_custom_target( my-icns ALL DEPENDS "${ICNS_PATH}" )
#
# For the associated utilities:
#
# - PNG: brew install imagemagick
# - SVG: brew cask install inkscape
#
# Enjoy!


function (make_icns_from_png)
cmake_parse_arguments (
ARG
""             # Boolean args
"INPUT;OUTPUT" # List of single-value args
""             # Multi-valued args
${ARGN})


find_program (
convert_exe
NAMES "convert" "convert.exe"
DOC "Path to ImageMagick convert")
if (NOT convert_exe)
message (FATAL_ERROR "Could not find ImageMagick's 'convert' - is ImageMagick installed?")
endif ()


get_filename_component (ARG_INPUT_ABS "${ARG_INPUT}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
get_filename_component (ARG_INPUT_ABS_BIN "${ARG_INPUT}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
get_filename_component (ARG_INPUT_FN "${ARG_INPUT_ABS_BIN}" NAME_WE)
get_filename_component (ARG_INPUT_DIR "${ARG_INPUT_ABS_BIN}" DIRECTORY)


set (sourceimg "${ARG_INPUT_ABS}")


set (basepath "${ARG_INPUT_DIR}/${ARG_INPUT_FN}")
set (output_icns "${basepath}.icns")
set (iconset "${basepath}.iconset")


set (deplist "")


foreach (size IN ITEMS 16 32 128 256 512)
math (EXPR size2x "2 * ${size}")


set (ipath "${iconset}/icon_${size}x${size}.png")
set (ipath2x "${iconset}/icon_${size}x${size}@2x.png")


list (APPEND deplist "${ipath}" "${ipath2x}")


add_custom_command (
OUTPUT "${ipath}"
COMMAND "${convert_exe}" ARGS "${sourceimg}" -resize "${size}x${size}" "${ipath}"
MAIN_DEPENDENCY "${sourceimg}"
COMMENT "ICNS resize: ${ipath}"
VERBATIM)


add_custom_command (
OUTPUT "${ipath2x}"
COMMAND "${convert_exe}" ARGS "${sourceimg}" -resize "${size2x}x${size2x}" "${ipath2x}"
MAIN_DEPENDENCY "${sourceimg}"
COMMENT "ICNS resize: ${ipath2x}"
VERBATIM)
endforeach ()


add_custom_command (
OUTPUT "${output_icns}"
COMMAND iconutil ARGS --convert icns --output "${output_icns}" "${iconset}"
MAIN_DEPENDENCY "${sourceimg}"
DEPENDS ${deplist}
COMMENT "ICNS: ${output_icns}"
VERBATIM)


if (ARG_OUTPUT)
set ("${ARG_OUTPUT}" "${output_icns}" PARENT_SCOPE)
endif ()
endfunction ()


function (make_icns_from_svg)
cmake_parse_arguments (
ARG
""             # Boolean args
"INPUT;OUTPUT" # List of single-value args
""             # Multi-valued args
${ARGN})


set (CMAKE_FIND_APPBUNDLE NEVER) # otherwise, it'll pick up the app bundle and open a shit ton of windows
find_program (
inkscape_exe
NAMES "inkscape" "inkscape.exe"
DOC "Path to Inkscape"
PATHS "/usr/local/bin" "/usr/bin")


message (STATUS "Inkscape path: ${inkscape_exe}")


if (NOT inkscape_exe)
message (FATAL_ERROR "Could not find Inkscape - is it installed?")
endif ()


get_filename_component (ARG_INPUT_ABS "${ARG_INPUT}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
get_filename_component (ARG_INPUT_ABS_BIN "${ARG_INPUT}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
get_filename_component (ARG_INPUT_FN "${ARG_INPUT_ABS_BIN}" NAME_WE)
get_filename_component (ARG_INPUT_DIR "${ARG_INPUT_ABS_BIN}" DIRECTORY)


set (sourceimg "${ARG_INPUT_ABS}")


set (basepath "${ARG_INPUT_DIR}/${ARG_INPUT_FN}")
set (output_icns "${basepath}.icns")
set (iconset "${basepath}.iconset")


set (deplist "")


foreach (size IN ITEMS 16 32 128 256 512)
math (EXPR size2x "2 * ${size}")


set (ipath "${iconset}/icon_${size}x${size}.png")
set (ipath2x "${iconset}/icon_${size}x${size}@2x.png")


list (APPEND deplist "${ipath}" "${ipath2x}")


add_custom_command (
OUTPUT "${ipath}"
COMMAND "${inkscape_exe}" ARGS -z -e "${ipath}" -w ${size} -h ${size} "${sourceimg}"
MAIN_DEPENDENCY "${sourceimg}"
COMMENT "ICNS resize: ${ipath}"
VERBATIM)


add_custom_command (
OUTPUT "${ipath2x}"
COMMAND "${inkscape_exe}" ARGS -z -e "${ipath2x}" -w ${size2x} -h ${size2x} "${sourceimg}"
MAIN_DEPENDENCY "${sourceimg}"
COMMENT "ICNS resize: ${ipath2x}"
VERBATIM)
endforeach ()


add_custom_command (
OUTPUT "${output_icns}"
COMMAND iconutil ARGS --convert icns --output "${output_icns}" "${iconset}"
MAIN_DEPENDENCY "${sourceimg}"
DEPENDS ${deplist}
COMMENT "ICNS: ${output_icns}"
VERBATIM)


if (ARG_OUTPUT)
set ("${ARG_OUTPUT}" "${output_icns}" PARENT_SCOPE)
endif ()
endfunction ()


function (make_icns)
cmake_parse_arguments (
ARG
""             # Boolean args
"INPUT;OUTPUT" # List of single-value args
""             # Multi-valued args
${ARGN})


if (NOT ARG_INPUT)
message (FATAL_ERROR "INPUT is required")
endif ()


if (NOT IS_ABSOLUTE "${ARG_INPUT}")
get_filename_component (ARG_INPUT "${ARG_INPUT}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
endif ()


if (NOT EXISTS "${ARG_INPUT}")
message (FATAL_ERROR "INPUT does not exist: ${ARG_INPUT}")
endif ()


file (RELATIVE_PATH ARG_INPUT "${CMAKE_CURRENT_SOURCE_DIR}" "${ARG_INPUT}")


get_filename_component (ARG_INPUT_EXT "${ARG_INPUT}" EXT)
if ("${ARG_INPUT_EXT}" STREQUAL ".png")
make_icns_from_png (INPUT "${ARG_INPUT}" OUTPUT child_output)
elseif ("${ARG_INPUT_EXT}" STREQUAL ".svg")
make_icns_from_svg (INPUT "${ARG_INPUT}" OUTPUT child_output)
else ()
message (FATAL_ERROR "INPUT must refer to a .png or .svg, but a ${ARG_INPUT_EXT} was provided")
endif ()


if (ARG_OUTPUT)
set ("${ARG_OUTPUT}" "${child_output}" PARENT_SCOPE)
endif ()
endfunction ()