Skip to content

Instantly share code, notes, and snippets.

@richellis
Forked from steverichey/Iconizer.sh
Last active September 15, 2021 22:42
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save richellis/09ccd6060d4e7ac7717d8767a2e27d39 to your computer and use it in GitHub Desktop.
Save richellis/09ccd6060d4e7ac7717d8767a2e27d39 to your computer and use it in GitHub Desktop.
Create iOS application icons from one PDF file. Requires ImageMagick.
#!/bin/sh
#
# Iconizer shell script by Steve Richey (srichey@floatlearning.com)
# Modified by Rich Ellis (rich@richellis.net) based on contributions on Github from crishoj, giria
# https://gist.github.com/steverichey/8493f3bd31ae71a9c933/forks
#
# This is a simple tool to generate all necessary app icon sizes and the JSON file for an *EXISTING* Xcode project from one file.
# To use: specify the path to your vector graphic (PDF format) and the path to your Xcode folder containing Images.xcassets
# Example: sh iconizer.sh MyVectorGraphic.pdf MyXcodeProject
#
# Requires ImageMagick: http://www.imagemagick.org/
# Requires GhostScript: http://www.ghostscript.com/
#
# Install dependencies with Homebrew: http://brew.sh/
# brew install imagemagic
# brew install ghostscript
# Exit on first error
set -e
if [ $# -ne 2 ]
then
echo "\nUsage: sh iconizer.sh file.pdf FolderName\n"
elif [ ! -e "$1" ]
then
echo "Did not find file $1, expected path to a vector image file.\n"
elif [ ${1: -4} != ".pdf" ]
then
echo "File $1 is not a vector image file! Expected PDF file.\n"
elif [ ! -d "./$2/Images.xcassets/AppIcon.appiconset/" ]
then
echo "Did not find Xcode folder $2, expected folder which contains Images.xcassets/AppIcon.appiconset/ \n"
elif [ ! -x "$(command -v convert)" ]
then
echo "Executable 'convert' not found in path. Please install ImageMagick."
elif [ ! -x "$(command -v gs)" ]
then
echo "Executable 'gs' not found in path. Please install GhostScript."
else
echo "Creating icons from $1 into $2/Images.xcassets/AppIcon.appiconset/..."
for i in 16 29 32 40 50 57 58 64 72 76 80 87 100 114 120 128 144 152 167 180 256 512 1024
do
echo "Creating $i px icon"
convert -density 400 $1 -scale $ix$i ./$2/Images.xcassets/AppIcon.appiconset/appicon_$i.png
done
echo "Created app icon files, writing Contents.json file..."
echo '{"images":[
{\n"size":"29x29",\n"idiom":"iphone",\n"filename":"appicon_29.png",\n"scale":"1x"\n},
{\n"size":"29x29",\n"idiom":"iphone",\n"filename":"appicon_58.png",\n"scale":"2x"\n},
{\n"size":"29x29",\n"idiom":"iphone",\n"filename":"appicon_87.png",\n"scale":"3x"\n},
{\n"size":"40x40",\n"idiom":"iphone",\n"filename":"appicon_80.png",\n"scale":"2x"\n},
{\n"size":"40x40",\n"idiom":"iphone",\n"filename":"appicon_120.png",\n"scale":"3x"\n},
{\n"size":"57x57",\n"idiom":"iphone",\n"filename":"appicon_57.png",\n"scale":"1x"\n},
{\n"size":"57x57",\n"idiom":"iphone",\n"filename":"appicon_114.png",\n"scale":"2x"\n},
{\n"size":"60x60",\n"idiom":"iphone",\n"filename":"appicon_120.png",\n"scale":"2x"\n},
{\n"size":"60x60",\n"idiom":"iphone",\n"filename":"appicon_180.png",\n"scale":"3x"\n},
{\n"size":"29x29",\n"idiom":"ipad",\n"filename":"appicon_29.png",\n"scale":"1x"\n},
{\n"size":"29x29",\n"idiom":"ipad",\n"filename":"appicon_58.png",\n"scale":"2x"\n},
{\n"size":"40x40",\n"idiom":"ipad",\n"filename":"appicon_40.png",\n"scale":"1x"\n},
{\n"size":"40x40",\n"idiom":"ipad",\n"filename":"appicon_80.png",\n"scale":"2x"\n},
{\n"size":"50x50",\n"idiom":"ipad",\n"filename":"appicon_50.png",\n"scale":"1x"\n},
{\n"size":"50x50",\n"idiom":"ipad",\n"filename":"appicon_100.png",\n"scale":"2x"\n},
{\n"size":"72x72",\n"idiom":"ipad",\n"filename":"appicon_72.png",\n"scale":"1x"\n},
{\n"size":"72x72",\n"idiom":"ipad",\n"filename":"appicon_144.png",\n"scale":"2x"\n},
{\n"size":"76x76",\n"idiom":"ipad",\n"filename":"appicon_76.png",\n"scale":"1x"\n},
{\n"size":"76x76",\n"idiom":"ipad",\n"filename":"appicon_152.png",\n"scale":"2x"\n},
{\n"size":"83.5x83.5",\n"idiom":"ipad",\n"filename":"appicon_167.png",\n"scale":"2x"\n},
{\n"size":"120x120",\n"idiom":"car",\n"filename":"appicon_120.png",\n"scale":"1x"\n},
{\n"size":"16x16",\n"idiom":"mac",\n"filename":"appicon_16.png",\n"scale":"1x"\n},
{\n"size":"16x16",\n"idiom":"mac",\n"filename":"appicon_32.png",\n"scale":"2x"\n},
{\n"size":"32x32",\n"idiom":"mac",\n"filename":"appicon_32.png",\n"scale":"1x"\n},
{\n"size":"32x32",\n"idiom":"mac",\n"filename":"appicon_64.png",\n"scale":"2x"\n},
{\n"size":"128x128",\n"idiom":"mac",\n"filename":"appicon_128.png",\n"scale":"1x"\n},
{\n"size":"128x128",\n"idiom":"mac",\n"filename":"appicon_256.png",\n"scale":"2x"\n},
{\n"size":"256x256",\n"idiom":"mac",\n"filename":"appicon_256.png",\n"scale":"1x"\n},
{\n"size":"256x256",\n"idiom":"mac",\n"filename":"appicon_512.png",\n"scale":"2x"\n},
{\n"size":"512x512",\n"idiom":"mac",\n"filename":"appicon_512.png",\n"scale":"1x"\n},
{\n"size":"512x512",\n"idiom":"mac",\n"filename":"appicon_1024.png",\n"scale":"2x"\n}\n],
"info":{\n"version":1,\n"author":"xcode"\n}\n}' > "./$2/Images.xcassets/AppIcon.appiconset/Contents.json"
echo "Complete!"
fi
@richellis
Copy link
Author

Newlines in the JSON generating code. Surprisingly you can just add an unescaped newline character and it works because the whole command string is wrapped in ' -- it formats both the script and the newline shows up in the output. I removed the extra \n so the JSON output doesn't have extra blank lines.

@mohemian-92817281
Copy link

Thanks for this, it was very helpful!

Just FYI, the script fails if you use an absolute path as the folder.

@Janneman84
Copy link

Janneman84 commented Dec 5, 2016

  • In new Xcode projects Images.xcassets is called Assets.xcassets
  • Notification icons are missing
  • You get a warning about AppIcon having an unassigned child (appicon_120.png), which is weird, no big deal though
  • It should be '# brew install imagemagick' (with a 'k).

My homebrew was messed up so I ended up uninstall and reinstalling it for it to work. It's not very fast, but the script works :)

@andrewpho
Copy link

andrewpho commented Jul 18, 2019

works, thanks! I updated it for the new XCode per Janneman84 and also added icons for notifications and IOS app store:
https://gist.github.com/andrewpho/a53d401eef601637c2d5d6ca9662ab43

@aoenth
Copy link

aoenth commented Sep 15, 2021

works, thanks! I updated it for the new XCode per Janneman84 and also added icons for notifications and IOS app store:
https://gist.github.com/andrewpho/a53d401eef601637c2d5d6ca9662ab43

Doesn't seem like your link works. Maybe you made it a secret gist?

@andrewpho
Copy link

Kevin, strangely the link does not work when clicked from comment display in Safari. However, if you copy and paste into URL box as text, it works.

@aoenth
Copy link

aoenth commented Sep 15, 2021

Gee you're right, thanks! Here is Andrew's link for people who are coming from the future:
Link to Andrew's Gist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment