Create iOS application icons from one PDF file. Requires ImageMagick & GhostScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/zsh | |
# | |
# | |
# Iconizer shell script by Steve Richey (srichey@floatlearning.com) | |
# Modified by Rich Ellis (rich@richellis.net) based on contributions on Github from crishoj, giria | |
# Further modified by Nick Pannuto (sneakyness@sneakyness.com) based on gist comments from previous forks | |
# https://gist.github.com/steverichey/8493f3bd31ae71a9c933/forks | |
# | |
# Changelog: | |
# - removed ./ from in front of $2's to allow for absolute paths | |
# - updated destination filename to target new 'Assets.xcassets' filename | |
# - uses zsh instead of sh | |
# - ran through ShellCheck until clean | |
# - updated with missing sizes | |
# - now pads pdf at h*83.33, w*75 of icon size (generally looks nicer) | |
# | |
# Todo: | |
# - padding and alignment options | |
# - insert missing sizes into correct slots | |
# - check for IM/GS up front | |
# - check if brew | |
# - installation prompts on missing deps | |
# | |
# 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 imagemagick | |
# brew install ghostscript | |
# Exit on first error | |
set -e | |
if [ "$#" -eq "0" ] | |
then | |
# TODO: check alias | |
printf "\nUsage:" | |
printf "\n sh iconizer.sh file.pdf FolderName" | |
printf "\n" | |
printf "\nOther Commands:" | |
printf "\n -alias Alias Installation Instructions" | |
printf "\n -deps Install ImageMagick and GhostScript via Brew 🍺" | |
printf "\n -help Display This Output" | |
printf "\n" | |
elif [[ $1 == '-help' ]] | |
then | |
sh "$0" | |
elif [[ $1 == '-alias' ]] | |
then | |
printf "\n" | |
if [ ! -d "$HOME/scripts" ] | |
then | |
printf "\n~/scripts does not exist, creating it" | |
mkdir "$HOME/scripts" | |
fi | |
printf "\ncopying %s to ~/scripts/%s" "$0" "$0" | |
cp "$0" "$HOME/scripts" | |
if (( ${+aliases[iconizer]} )) | |
then | |
whence iconizer | |
else | |
echo "iconizer not aliased, adding alias to zshrc" | |
echo "alias iconizer=\"zsh $HOME/scripts/iconizer.sh\"" >> "$HOME/.zshrc" | |
fi | |
elif [[ $1 == '-deps' ]] | |
then | |
# TODO: check for brew? | |
# TODO: check versions first? | |
brew install imagemagick | |
brew install ghostscript | |
elif [ $# -ne 2 ] | |
then | |
# TODO: check if aliased or using script | |
printf "\nUsage: sh iconizer.sh file.pdf FolderName\n" | |
elif [ ! -e "$1" ] | |
then | |
printf "\nDid not find file %s, expected path to a vector image file.\n" "$1" | |
elif [ "${1: -4}" != ".pdf" ] | |
then | |
printf "\nFile %s is not a vector image file! Expected PDF file.\n" "$1" | |
elif [ ! -d "$2/Assets.xcassets/AppIcon.appiconset/" ] | |
then | |
# TODO: ask to install IM | |
# TODO: better search for assets folder | |
printf "\nDid not find Xcode folder %s, expected folder which contains Assets.xcassets/AppIcon.appiconset/ \n" "$2" | |
elif [ ! -x "$(command -v convert)" ] | |
then | |
printf "\nExecutable 'convert' not found in path. Please install ImageMagick.\n" | |
elif [ ! -x "$(command -v gs)" ] | |
then | |
# TODO: ask to install GS | |
printf "\nExecutable 'gs' not found in path. Please install GhostScript.\n" | |
else | |
printf "Generating icons from" | |
printf "\n %s" "$1" | |
printf "\n into" | |
printf "\n %s/Assets.xcassets/AppIcon.appiconset/…\n" "$2" | |
printf "\nFor Sizes:\n" | |
# TODO: split into groups for | |
# iphone, ipad, carplay, mac, applewatch | |
# TODO: toggle groups | |
# TODO: extra size options | |
# TODO: Padding opt | |
for i in 16 20 29 32 40 48 50 55 57 58 60 64 72 76 80 87 88 100 114 120 128 144 152 167 172 180 196 216 256 512 1024 | |
do | |
# height is 83.33% of image size | |
# width is 75% of image size | |
sH=$(bc <<< "$i * 0.8333") | |
sW=$(bc <<< "$i * 0.75") | |
printf "%sx%s " "$i" "$i" | |
convert -density 463 "$1" -background transparent -gravity center -scale ""$sW"x$sH" -extent ""$i"x$i" "$2"/Assets.xcassets/AppIcon.appiconset/appicon_$i.png | |
done | |
printf "\n Images successfully generated…" | |
printf "\n Writing Contents.json file…\n" | |
printf '{"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/Assets.xcassets/AppIcon.appiconset/Contents.json" | |
printf "\n🎉 Complete! 🎉\n" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment