web-dev-qa-db-fra.com

Comment créer manuellement des fichiers icns en utilisant iconutil?

Lorsque je valide mon application, le message d'erreur suivant s'affiche: 

l'ensemble d'applications ne contient pas d'icône au format ICNS, contenant à la fois une image 512x512 et une image 512x512@2x.

J'utilise pour faire les icônes icns avec Img2icns app et jusqu'à aujourd'hui, cela fonctionnait toujours correctement. Mais maintenant, je reçois cette erreur et il n'y a aucun moyen de la faire fonctionner. J'ai essayé de mettre deux fichiers PNG ensemble (512x512 et 1024x1024) dans Img2icns mais je reçois toujours cette erreur. J'ai également essayé de suivre les instructions de la directive d'interface humaine OS X d'Apple, mais lorsque j'essaie de créer les jeux d'icônes, j'obtiens cette erreur de terminal:

-bash: erreur de syntaxe près du jeton inattendu 'newline'

Je ne suis pas très bon avec les commandes de terminal, alors peut-être que je fais quelque chose de mal. J'ai écrit:

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

Si quelqu'un pouvait aider, ce serait très apprécié. Merci Massy.

90
Blue

Commander les instructions suivantes ( link ):

Utiliser iconutil pour créer un fichier icns manuellement 

L'outil de ligne de commande iconutil convertit les dossiers iconset en fichiers icns haute résolution prêts pour le déploiement. (Vous pouvez trouver une documentation complète sur cet outil en entrant man iconutil dans Terminal.) À l'aide de cet outil, le fichier icns résultant est également compressé. Il n'est donc pas nécessaire d'effectuer une compression supplémentaire.

Pour convertir un ensemble d'icônes en fichier icns

Entrez cette commande dans la fenêtre du terminal:

iconutil -c icns <iconset filename>

<iconset filename> est le chemin d'accès au dossier contenant le jeu d'icônes que vous souhaitez convertir en icns. La sortie est écrite au même emplacement que iconset file, sauf si vous spécifiez un fichier de sortie comme indiqué:

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

En d'autres termes, vous devez remplacer <iconset filename> par le chemin:

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

Comme le chemin contient des espaces, vous devez utiliser des guillemets, par exemple:

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

Cette commande devrait fonctionner correctement.

55
Anne

Voici un script pour convertir un fichier png 1024x1024 (nommé "Icon1024.png") dans le fichier icns requis. Enregistrez-le dans un fichier appelé "CreateICNS.src" dans le dossier où se trouve votre fichier png dans le terminal "cd" dans le même dossier et tapez "source CreateICNS.src" pour l'appeler:

mkdir MyIcon.iconset
sips -z 16 16     Icon1024.png --out MyIcon.iconset/icon_16x16.png
sips -z 32 32     Icon1024.png --out MyIcon.iconset/[email protected]
sips -z 32 32     Icon1024.png --out MyIcon.iconset/icon_32x32.png
sips -z 64 64     Icon1024.png --out MyIcon.iconset/[email protected]
sips -z 128 128   Icon1024.png --out MyIcon.iconset/icon_128x128.png
sips -z 256 256   Icon1024.png --out MyIcon.iconset/[email protected]
sips -z 256 256   Icon1024.png --out MyIcon.iconset/icon_256x256.png
sips -z 512 512   Icon1024.png --out MyIcon.iconset/[email protected]
sips -z 512 512   Icon1024.png --out MyIcon.iconset/icon_512x512.png
cp Icon1024.png MyIcon.iconset/[email protected]
iconutil -c icns MyIcon.iconset
rm -R MyIcon.iconset
236
Aidan

Il existe un module de noeud de ligne de commande qui effectue tout le travail de conversion d'un fichier PNG dans un répertoire iconset:

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

Ces commandes (entrées dans Terminal) m'ont permis de convertir un ancien fichier icns au nouveau format:

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

Mettre à jour

Le paramètre -c de iconutil n'est plus pris en charge. Utilisez --convert à la place:

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
12
Aidan

Bien que l’utilisation de toutes sortes de scripts pour convertir une image PNG haute résolution en une pléiade de copies basse résolution différentes puisse sembler pratique (et elle le l'est vraiment), il ne faut pas oublier que ce type de redimensionnement automatique rendra les images imparfaites de manière perceptible.

Plus la résolution est faible, plus l'icône est floue!

Au lieu de cela, vous devez toujours demander un logo sous un format vectoriel, par exemple, dans SVG, à votre concepteur. Avec cet outil en main, vous pouvez préparer manuellement des fichiers PNG parfaits dans toutes les résolutions requises, puis créer un fichier .icns unique, qui rendra l’icône de votre application magnifique sur chaque écran, du téléphone portable à l’affichage Retina haut de gamme du système. dernier iMac.

À partir de la dernière directive Apple à compter de 2016, vous devez préparer les fichiers PNG suivants:

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

Une fois tous les fichiers PNG préparés, placez-les dans un répertoire avec l'extension .iconset (Logos.iconset par exemple) et exécutez-le à partir du terminal:

iconutil --convert icns Logos.iconset

S'il n'y a pas eu d'erreur après l'exécution de cette commande, tous les fichiers ont été préparés correctement et vous avez le fichier Logos.icns dans le même répertoire, contenant tous les beaux logos nets de votre application qui conviendra à tout écran moderne à partir de 2017.

9
TranslucentCloud

Commentaire supplémentaire, lorsque vous créez le fichier .icns, vous devez renommer tous les fichiers d'image avec le préfixe "icon_ ". Sinon, iconutil échouera avec le message d'erreur suivant: ".iconset: error: Impossible de générer ICNS." ce qui n'est pas informatif du tout.

8
Bearsu

J'ai écrit un script bash pour créer des icns à partir d'un fichier svg:

#!/usr/bin/env bash 
sizes=(16 32 64 128 256 512)
largfile='[email protected]'
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'     '[email protected]'
mv 'icon_64x64.png'     '[email protected]'
cp 'icon_256x256.png'   '[email protected]'
cp 'icon_512x512.png'   '[email protected]'

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

Assurez-vous que imagemagick est installé avec le support librsvg, sur mac:

brew install imagemagick --with-librsvg

Ce script m'a bien servi. 


Mettre à jour

Pour un traitement plus complet, j'ai créé un outil de ligne de commande (écrit en Swift) permettant de générer AppIcon.appiconset avec la présentation et le format corrects:

https://github.com/kindlychung/genicon

5
qed

J'ai refactored @ le script de Henry pour le rendre meilleur:

#!/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

Mettre à jour

Le paramètre -c de iconutil n'est plus pris en charge. Utilisez -—convert à la place:

#!/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
5
dardo82

Lorsque je valide mon application, le message d'erreur suivant s'affiche:

l'ensemble d'applications ne contient pas d'icône au format ICNS, contenant à la fois une image 512x512 et 512x512 @ 2x.

Je ne suis pas très bon avec la commande de terminal et peut-être que je fais quelque chose de mal. J'ai écrit:

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

D'une part, comme je l'ai mentionné dans un commentaire sur la réponse d'Anne, vous n'avez probablement pas besoin d'utiliser iconutil. Vous devriez pouvoir simplement ajouter le jeu d'icônes à votre projet et laisser Xcode le convertir pour vous dans le cadre de la construction.

De toute façon, cela peut être votre problème:

J'ai essayé de mettre deux fichiers PNG ensemble (512x512 et 1024x1024)… mais je reçois toujours l'erreur.

Il n'y a pas de taille 1024 par 1024 points. L'élément de 1024 x 1024 pixels (ce qui représentait 1024 points avant Mountain Lion) est maintenant utilisé pour 512 par 512 points @ 2x.

Votre fichier PNG doit être nommé de manière appropriée: [email protected]

3
Peter Hosey

L’ancienne version 2.2 d’Icon Composer d’Apple fonctionne très bien, vous n’avez qu’à ouvrir le fichier .ICNS qu’elle contient, appuyez sur le bouton 1024x1024 et ajoutez votre image.

3
valexa

Dead simple .png ???? .icns

  1. Télécharger IconMaker.app C'est juste un .applescript ne mord pas
  2. Faites glisser votre fichier .png sur le fichier IconMaker.app que vous venez de créer.

Plus d'infos: http://eon.codes/blog/2016/12/06/Creating-an-app-icon/

High Sierra updateiconutil est maintenant plus strict en ce qui concerne la taille du fichier source .png. Plus d'informations à ce sujet dans l'article de blog après le saut. ✌️

3
eonist

Le code Shell de @ dardo82 est bon et efficace . En voici un plus simple en sh (pour tous les * nix) et plus rapide (comme si c'était vraiment important):

#!/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
2
MichaelT

Exécuter iconutil -c icns Icon.iconset

Remarque

  • Icon.iconset est un dossier
  • Le nom commence par la lettre minuscule icon_
  • Lorsque vous voyez Icon.icns avec l'image correcte, vous savez que cela fonctionne.

 enter image description here

2
onmyway133

Il y a 2 tâches:
- créer 10 fichiers icns corrects
- obtenez votre projet Xcode pour les utiliser correctement 

Comme j'avais des problèmes d'une heure avec ces deux tâches, et que je n'aime pas trop quand je ne "vois" pas ce qui se passe, voici un chemin pour les plus prudents: 

Créez 10 fichiers icns corrects:
J'ai utilisé le script ci-dessus de Henry: Il fonctionne toujours pour HighSierra et Xcode 9.2, y compris la commande 'c'.
Le fichier icns que j’ai obtenu apparaît sous la forme d’une seule taille d’icône dans le Finder/Quicklook et dans l’aperçu n’affiche que 8 tailles sur 10.
J'ai donc utilisé terminal, accédé à cd dans mon dossier et utilisé la commande suivante: iconutil -c iconset (nom de fichier icns) sur le fichier icns qui vient d'être créé pour rétablir le fichier icns dans un dossier d'icônes, et - lo & behold - Je pouvais voir mes 10 fichiers d'icônes nouvellement créés. En utilisant Vue rapide sur le dossier iconset (et en utilisant le mode plein écran pour pouvoir les zoomer avec le curseur), je pouvais vérifier que toutes les tailles semblaient vraiment bien.

Soit dit en passant: ils étaient plus beaux que mes tentatives de redimensionnement avec PSE, probablement parce que je n'ai pas pris le temps de jouer avec toutes les options de redimensionnement dans PSE. Si vous utilisez PSE, assurez-vous que vos fichiers png sont enregistrés sans profil de couleur. En outre, avouant mon ignorance, un fichier 256x256 @ 2 est pour moi identique à un fichier 512x512, les deux en 72 ppp. Essayer de suivre les commentaires de 144 dpi ci-dessus n'a pas fonctionné pour moi. 

Demandez à votre projet Xcode de les utiliser correctement:
Tout d’abord, j’ai supprimé toutes mes tentatives infructueuses au sein de Xcode et engagé une version propre dans le référentiel git (ce qui aurait été intelligent, aurait été de commettre une version propre en premier - avant que je ne commence frénétiquement à ajouter l’icône odyssee).
Je me suis également assuré que, dans le fichier info.plist, il n'y avait pas de pointeur lié à l'entrée 'icon file' et que, dans les paramètres généraux de mon projet, j'avais choisi AppIcon pour les icônes d'application.
Ensuite, j'ai ajouté un catalogue assets.asset et, dans le catalogue des actifs, un nouveau dossier AppIcon 'AppIcons and Launch Images' pour système d'exploitation.
Ensuite, j'ai copié (glissez-déposez avec l'option enfoncée) du dossier iconset chaque fichier d'image png dans le détenteur respectif de l'espace AppIcon. Encore une fois, je pouvais voir ce qui se passait. Xcode l'a convertie en fichiers icns, ou peut-être - comme mon dossier iconset est dérivé d'un dossier icns - les formats de fichiers ont été acceptés. 

Ensuite, archivez et validez et il n'y aura aucune erreur lors du téléchargement ou de la validation. 

1
Uwe

Identique à @Henry (commentaire ci-dessus), mais prend en argument le nom de fichier PNG et génère l'ICNS du même nom.

REMARQUE: Le nom de fichier PNG ne devrait comporter qu'un seul point pour une extension distincte, c'est-à-dire xpto.png.

Enregistrez donc le code ci-dessous dans un fichier nommé "CreateICNS.src" dans le dossier contenant votre fichier png.

CODE:

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/[email protected]
sips -z 32 32     $1 --out $ICONSET/icon_32x32.png
sips -z 64 64     $1 --out $ICONSET/[email protected]
sips -z 128 128   $1 --out $ICONSET/icon_128x128.png
sips -z 256 256   $1 --out $ICONSET/[email protected]
sips -z 256 256   $1 --out $ICONSET/icon_256x256.png
sips -z 512 512   $1 --out $ICONSET/[email protected]
sips -z 512 512   $1 --out $ICONSET/icon_512x512.png
cp $1 $ICONSET/[email protected]
iconutil -c icns $ICONSET
rm -R $ICONSET

COMMENT UTILISER :

Puis dans le terminal, "cd" dans le même dossier et tapez:

source CreateICNS.src {PNG filename}

où {NomFichier PNG} est le nom de votre fichier PNG, c'est-à-dire xpto.png.

Si votre fichier s'appellerait abc.png, vous utiliseriez:

source CreateICNS.src abc.png
1
Telmo Dias

Voici une fonction principalement basée sur l'exemple de Henry (pourrait être utile dans ~/.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/[email protected]
        iconutil -c icns "$filename".iconset
        rm -r "$filename".iconset
    fi
}

Usage:

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

Crée 10 tailles de 16x16 à 512x512@2x; accepte les images d'entrée en .png format seulement.

0
l'L'l

Bonjour, pour mes besoins j'ai fait un droplet qui fonctionne en glissant-déposant des icônes seules ou des icônes pour rechercher dans un dossier (je me suis limité aux dossiers car les recherches sur les volumes de toutes les icônes peuvent prendre beaucoup de temps). Ainsi, par glisser-déposer, vous pouvez déposer des dossiers ou des applications, tout ce qui peut contenir une icône. L'ensemble d'icônes créé porte le nom de l'icône d'origine, il est placé dans un répertoire "/ aaaicones" et le chemin de l'icône. Exemple dans le dossier "/ aaaicones si vous soumettez xcode.app, vous trouverez "/Aaaicones/Applications/xcode.app/access.iconset "et /aaaicones/Applications/xcode.app/access.icns (l'icône recréée ) il y aura un fichier texte où sera tracé le chemin complet des icônes, ainsi que le chemin de l'exemple d'icônes correspondant "/ Applications/xcode.app/Contenu/Applications/Instruments.app/Contenu/Frameworks/InstrumentsPlugIn .framework/Versions/A/Ressources/access.icns ""/aaaicones/Applications/xcode.app/access.iconset "dans l'exemple pris (xcode), cela peut créer un dossier à la fin (avec toutes les icônes et iconset) de 214 Mo. Si vous traitez une icône seule, elle sera placée dans le répertoire "/ aaaicones/aIconeseule /" et son chemin d’origine, exemple/aaaicones/aIconeseule/Mac Elcapitan/.VolumeIcon.icns et/aaaicones/aIconeseule/Mac Elcapitan /.VolumeIcon.iconset avec/aaaicones/aIconeseule/Mac Elcapitan/aalisticones.txt La gouttelette se trouve en dessous

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
0
deek5

J'avais besoin de ça, mais pour CMake. Je voulais aussi l'option de lui donner un SVG.

Voici le Gist: https://Gist.github.com/Qix-/f4090181e55ea365633da8c3d0ab5249

Et le code 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 ()
0
Qix