Generating iOS App Icons via ImageMagick

Oftentimes you find yourself having to generate multiple sized icons for your iOS app. There are applications on the app store that help you do this, as well as websites. You are at the mercy of them having been updated on time to support new versions of iOS / iPad OS / etc. Wouldn’t it be nice if you could have this as a scheme/target in your app that you could update yourself as needed?

Let me show you how!

We created a new iOS/iPad OS (On macOS Big Sur 11.6, Xcode 13.0) project called OneCoolApp. Let’s add a new aggregate target:

Change the new target name to GenerateAppIcons. Now let’s add a new Run Script phase:

macOS uses zsh by default and is included on recent macos installations. We use a feature of it called an Associative Arrays. Make sure to change the shell like so:

Now for the script content. Copy paste this in:

PATH="/opt/local/bin:/opt/local/sbin:$PATH" # Needed for my personal dev machine
ROOT_IMAGE_PATH="$SOURCE_ROOT/OneCoolApp/Assets.xcassets/AppIcon.appiconset/AppStoreIcon.png"

APP_ICON_PATH="$SOURCE_ROOT/OneCoolApp/Assets.xcassets/AppIcon.appiconset/"

declare -A APP_ICON_SIZING # That aforementioned associative array

APP_ICON_SIZING[iphone-20pt@2x]="40x40"
APP_ICON_SIZING[iphone-20pt@3x]="60x60"

APP_ICON_SIZING[iphone-29pt@2x]="58x58"
APP_ICON_SIZING[iphone-29pt@3x]="87x87"

APP_ICON_SIZING[iphone-40pt@2x]="80x80"
APP_ICON_SIZING[iphone-40pt@3x]="120x120"

APP_ICON_SIZING[iphone-60pt@2x]="120x120"
APP_ICON_SIZING[iphone-60pt@3x]="180x180"

APP_ICON_SIZING[ipad-20pt@1x]="20x20"
APP_ICON_SIZING[ipad-20pt@2x]="40x40"

APP_ICON_SIZING[ipad-29pt@1x]="29x29"
APP_ICON_SIZING[ipad-29pt@2x]="58x58"

APP_ICON_SIZING[ipad-40pt@1x]="40x40"
APP_ICON_SIZING[ipad-40pt@2x]="80x80"

APP_ICON_SIZING[ipad-76pt@1x]="76x76"
APP_ICON_SIZING[ipad-76pt@2x]="152x152"

APP_ICON_SIZING[ipad-83.5pt@2x]="167x167"

for name size in ${(kv)APP_ICON_SIZING};
do
    convert $ROOT_IMAGE_PATH -resize $size\! $APP_ICON_PATH/Icon-$name.png
done

First notice that ROOT_IMAGE_PATH points to the largest image in our asset library. Let’s add an image in that spot before we run this scheme/target. Name it AppStoreIcon.png. Feel free to use the following image:

After adding it should look like this in your project:

One more thing before we run the scheme/target! We need to make sure that ImageMagick is installed. I used MacPorts (via $ sudo port install ImageMagick) but you may install it via other means. That’s what the convert command uses in the shell script.

Build the scheme/target having selected it like so:

Your assets should now look like this!

Drag and drop the unassigned icons to their proper places in the assets library so it looks like so:

You are good to go! If the app store icon ever changes you just need to run this scheme/target and it will regenerate your assets for you.

Let’s try that out actually. Here is a new (hastily designed moon/banana/boomerang) app store icon for us to use:

Your assets library should look like this after adding it:

Build the GenerateAppIcons scheme/target again… amazing. Your suns have turned into moons/bananas/boomerangs:

Pretty cool! This saves time when working with icons that are changing, can be extended to include app extensions as well (such as iMessage extensions) watch apps, etc… when new devices are introduced you just have to update your shell script to output those new sizes and add them to your assets library, rather than waiting for third party tools to update.

There are some downsides… Oftentimes the app icons don’t scale nicely from 1024×1024 down to 20×20. You’ll have to get your designer to design icons that small that highlight the fine features from the large icon that you want to communicate. Some extensions have odd sizes as well, such as some icons needed in an iMessage extension, like 74×55.

For a large subset of use cases though this technique can save a lot of time.