怎样在编译的时候改变你的App图标

使用Xcode, ImageMagickshell脚本, 本教程演示了如何在构建时基于当前构建配置生成应用程序图标, 并可能向您介绍Xcode的一些鲜为人知的功能. 下方示例图片是最终的效果图(在原有的图标上增加了Beta功能区和内部版本号).
怎样在编译的时候改变你的App图标_第1张图片

您是否相信在本教程中您不会编写任何一行Swift ? 不, 严肃地说, 你也不会写任何Objective-C. :]

本教程将让您只编写bash shell脚本。 您将使用一个名为ImageMagick的工具,TerminalXcode来编写一个脚本,该脚本会自动将构建版本号和“调试”或“测试版”功能区小角标覆盖到应用程序的图标上.

本教程假设您具有Unix脚本的一些基本知识。 您可以在不成为shell脚本专家的情况下继续学习,但您也可以在Bash初学者指南或高级Bash脚本编制指南中查找所需内容。

所以,你想要开始吗?

Getting Started (开始)

首先,您需要安装ImageMagick,这是一个功能强大的图像处理软件套件,并且您只需通过终端就能够与其进行交互。

您可以通过Homebrew很方便地安装ImageMagick.

如果您没有 Homebrew , 或者不知道它是什么, 你可以通过这个工具的主页来了解它, 并学习怎样安装.

如果你已经安装了 Homebrew, 启动终端并输入下面的命令仍然是一个好主意.

brew update

这将确保您获得从Homebrew安装的任何软件都是最新版本。 如果您没有安装Homebrew,它也会通知您。

OK cool, Now, 运行如下的命令:

brew install ImageMagick

怎样在编译的时候改变你的App图标_第2张图片
您还需要安装软件套件Ghostscript,因为ImageMagick中需要的文本功能依赖于它。 Ghostscript是一个专为渲染PDF和PS文件而设计的软件套件。 你需要它,因为它为ImageMagick提供了字体支持。通过运行如下命令来安装Ghostscript.

brew install ghostscript

如果你稍后遇到任何困难,请运行以下命令:

brew doctor

如果出现任何问题,您将收到有关它的消息,以及如何修复它的说明。

这就是您需要安装才能完成本教程的所有东西。

Hello Llama

ImageMagick 有许多命令, 但本教程仅会用到两个 - convert(转变)和composite(混合).

  • convert拿到一张图像,修改图像,然后将结果保存为新图像。
  • composite持有一张图像,将其覆盖在另一个图像上,并将结果输出到第三个图像。

本教程提供了一些示例图标供您使用。 当然,您可以使用自己的,但您需要相应地调整文件名。 下载示例图标,为了本教程的目的,将它们放在桌面上。

教程的目标之一是将构建版本号(build version)覆盖在应用程序的图标上。 因此,通过将Hello World放在其中一个图标上您将看到如何来使用ImageMagick将文本覆盖在图像上。 打开终端并导航到应用程序图标文件夹:

cd ~/Desktop/AppIconSet

Now, type:

convert [email protected] -fill white -font Times-Bold -pointsize 18 -gravity south -annotate 0 "Hello World" test.png
  • [email protected]是输入图片的文件名;
  • fill white将文字的填充颜色设为白色;
  • font Times-Bold指示ImageMagick对所有文本使用Times字体的粗体变体;
  • pointsize 18设置字体为18像素;
  • gravity south表示命令生成的任何文本都将在图像的底部对齐;
  • **annotate 0 “Hello World”**告诉ImageMagick使用文本Hello World以0度的角度注释图像;
  • test.png是输出文件的名字, 并且ImageMagick将会覆盖已经存在的同名文件;

如果你在屏幕上未看到任何错误, 你将在AppIconSet文件夹中看到一个名为test.png的文件, 并且, 它看起来将会如下图所示:
怎样在编译的时候改变你的App图标_第3张图片

Note: 如果您收到错误消息或脚本无法正常工作,则可能是您没有安装必要的字体。 要找出可用的字体,请在终端中运行以下命令:

convert -list font

如果您没有Times字体,请从列表中选择一个替换使用。

OK, 完成以上内容, 下面将会在图片的右上角放置一条Beta丝带. 在终端输入:

composite betaRibbon.png test.png test2.png

这句命令将betaRibbon.png放置在test.png上面, 然后将这张混合图片保存为test2.png.

打开test2.png. Wait, 它看起来和原始的test.png没什么区别!
怎样在编译的时候改变你的App图标_第4张图片
下面是到底发生了什么的分析:

test.png的大小为120 x 120像素。 但是,betaRibbon.png是1024×1014像素,因此只有betaRibbon.png的透明部分应用于test.png,其余部分被裁剪。

不相信我? 尝试运行相同的命令,但交换betaRibbon.png和test.png的位置:

composite test.png betaRibbon.png test2.png

现在,您将看到一个更大的图像,其中一直是功能区,并且test.png图像在左上角对齐:

怎样在编译的时候改变你的App图标_第5张图片
为了使其正常工作,您需要将betaRibbon.png的大小调整为120 x 120.这在ImageMagick中非常简单 - 只需输入:

convert betaRibbon.png -resize 120x120 smallBetaRibbon.png

此命令将betaRibbon.png的大小调整为120 x 120像素,并将结果保存为smallBetaRibbon.png

Now, execute the following:

composite smallBetaRibbon.png test.png test2.png

打开test2.png,你会看到它现在看起来应该是:
怎样在编译的时候改变你的App图标_第6张图片
这就是本教程所需的所有ImageMagick功能,但要知道这只是ImageMagick可以做的事情的冰山一角。 查看ImageMagick的主页以了解更多信息。


Xcode

完成所有图像处理工作后,是时候通过在熟悉的领域工作来清洁您的味觉。

打开Xcode,选择File \ New \ Project …,选择iOS \ Application \ Single View Application模板,然后单击Next。 将项目命名为Llama Trot,将所选语言设置为Swift,并将设备系列设置为Universal。 为简单起见,将项目保存到桌面

您的目标是在每次构建项目时,让Xcode和ImageMagick生成适当的图标,具体取决于所选的构建配置。

Xcode能够在构建项目时使用运行脚本来执行操作。 运行脚本只是一个Unix脚本,就像您已编写的那样,每次运行Xcode项目时都会执行。

Setting Up a Run Script (设置运行脚本)

在您的项目中,选择Llama Trot目标,然后导航到Build Phases。 单击+图标,然后从弹出菜单中选择New Run Script Phase
怎样在编译的时候改变你的App图标_第7张图片
您将看到运行脚本阶段已添加到项目的阶段。

在该运行脚本中,Shell参数应自动设置为bin / sh,这意味着该脚本将在bash Unix shell中执行。

shell参数下面是一个框,供您输入脚本。 在该框中键入以下行:

echo "Hello World"

你的新编译阶段应该看起来如下所示:
怎样在编译的时候改变你的App图标_第8张图片
编译并运行。 你应该看到没什么有趣的。 那是因为脚本在您不看的时候将 Hello World 打印到您的构建日志中。

导航到Report Navigator - 这是Xcode导航器窗格最右侧的图标 - 然后单击最新的构建报告,如下图所示。 在描述Xcode为您构建项目时所做的所有工作的文本墙中,您将看到文本 Hello World
怎样在编译的时候改变你的App图标_第9张图片

App Icons (应用图标)

太棒了,你已经有了一个输出 Hello World 的脚本,就像你在开发人员的职业生涯中这一点可能做了一百万次。 现在是时候修改应用程序图标了。

Finding the App Icons From Your Script (从您的脚本中查找应用程序图标)

通过导航到Xcode中的Images.xcassets并将每个图标拖到AppIcon图像集中的相应图块中,将所有应用图标添加到Images.xcassets资产目录:
怎样在编译的时候改变你的App图标_第10张图片
您还需要将debugRibbon.pngbetaRibbon.png放在项目的根目录中 - 与项目的.xcodeproj文件所在的文件夹相同。
怎样在编译的时候改变你的App图标_第11张图片
为了对图标执行任何操作,您的脚本需要知道它们的位置。 用以下代码替换您的运行脚本:

echo "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
echo "${SRCROOT}"
  1. 第一行打印运行项目后将包含最终图标的文件夹的路径。
  2. 第二行打印项目文件所在的文件夹路径。

这可以通过使用Xcode的许多构建设置变量来实现。

运行项目并检查构建报告。 您应该看到描述项目最终产品位置的文件夹路径。 在此之下,您应该看到项目目录的文件夹路径:
怎样在编译的时候改变你的App图标_第12张图片
(在Finder中)导航到上图打印出的第一条路径并查看其中的内容; 您将看到应用的所有产品,包括所有应用图标。 这是您保存ImageMagick修改的图标的地方。

要查看这些图标,请右键单击该文件夹中的应用程序图标,然后选择显示包内容。 现在看起来很普通!
怎样在编译的时候改变你的App图标_第13张图片
现在导航到您echo的第二个文件夹路径。 这只是您正常的项目文件夹。 那么应用程序图标在哪里?

进入与项目同名的文件夹 - 在本例中为“Llama Trot”。 在那里你会看到Images.xcassets。 打开Images.xcasset,您将看到另一个名为AppIcon.appiconset的文件夹。

应用程序图标位于该文件夹中,您将使用ImageMagick对其进行修改。 假设您将项目保存到桌面并命名为Llama Trot,图标的路径为**〜/ Desktop / Llama \ Trot / Llama \ Trot / Images.xcassets / AppIcon.appiconset**

你要作弊来获得初始图标的完整路径,所以用以下代码替换脚本的最后一行:

IFS=$'\n'
echo $(find ${SRCROOT} -name "[email protected]")
  1. 第一行临时将IFS内部字段分隔符设置为换行符。 如果你不这样做,第二行将失败,因为如果你对发生的事情感到好奇,文件名Llama Trot包含一个空格尝试注释掉第一行。
  2. 此命令中的第二行递归搜索$ {SRCROOT}文件夹以获取文件[email protected]

顺便说一句,重要的是你输入行IFS = $'\ n'正好显示 - 在= sign的两侧没有空格。

运行该项目,您将看到AppIcon60x60 @ 2x的完整路径回显:
怎样在编译的时候改变你的App图标_第14张图片

Putting It All Together (将其放在一起)

艰苦的工作结束了。 现在是时候把所有东西放在一起,让你的脚本正确地修改应用程序图标。 您将从仅修改[email protected]开始,然后为所有应用程序图标进行一般化。 这意味着您需要使用视网膜@ 2x iPhone模拟器或设备进行测试,而不是iPhone 6+。

通过结合ImageMagick和先前脚本的技术,您最终得到以下脚本。 确保相应地更新脚本:

IFS=$'\n'
#1
PATH=${PATH}:/usr/local/bin

#2
TARGET_PATH="${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/[email protected]" 
BASE_IMAGE_PATH=$(find ${SRCROOT} -name "[email protected]") 

#3
convert betaRibbon.png -resize 120x120 resizedBetaRibbon.png 

#4
convert ${BASE_IMAGE_PATH} -fill white -font Times-Bold -pointsize 18 -gravity south -annotate 0 "Hello World" - | composite resizedBetaRibbon.png - ${TARGET_PATH}

这是发生了什么的细分:

  1. 如果省略此行,构建将失败。您的终端有一个名为PATH的变量,用于存储默认脚本位置列表。终端在那里首先查找默认情况下不属于Unix的任何命令。这允许位于PATH目录中的任何命令在不指定命令的完整位置的情况下运行。 Xcode需要与终端共享相同的PATH变量。此行将/user/local/bin添加到Homebrew安装其包的PATH变量中。
  2. 接下来的两行获取应用程序图标的位置,如前所述,然后将每个路径分别保存到变量TARGET_PATHBASE_IMAGE_PATH中;
  3. 此线将右上角β色带的尺寸调整到合适的尺寸;
  4. 最后一行一次完成两件事。首先,它使用文本 Hello World 注释初始应用程序图标。然后脚本pipe into复合函数(这就是|符号的作用) , 并将调整大小的beta功能区放在它上面。 ImageMagick使用短划线“ - ”而不是文件名来完成此操作。该脚本将结果保存为产品应用程序图标。

**注意:**应用程序图标名称不是任意的。 应用程序图标的名称必须与最终产品中的[email protected]类似。 Xcode使用此命名约定来根据正在使用的设备确定要使用的图标。

运行应用程序并转到设备的主屏幕以查看应用程序的图标; 如果你在模拟器上,按Cmd + Shift + H进入主屏幕。 你应该看到一个修改过的图标:
怎样在编译的时候改变你的App图标_第15张图片

The Rest of the Icons (其它的应用图标)

现在您已经完成了一个图标,现在是时候将脚本概括为适应所有图标,因此可以使用iPad图标,iPhone 6+图标等。

为此,您需要将图标修改代码转换为将图标名称作为参数的函数。 然后为您拥有的每个图标执行该功能。

修改脚本,使其如下所示:

PATH=${PATH}:/usr/local/bin
IFS=$'\n'

function generateIcon () {
  BASE_IMAGE_NAME=$1
    
  TARGET_PATH="${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/${BASE_IMAGE_NAME}"
  BASE_IMAGE_PATH=$(find ${SRCROOT} -name ${BASE_IMAGE_NAME})
    
  WIDTH=$(identify -format %w ${BASE_IMAGE_PATH})
    
  convert betaRibbon.png -resize $WIDTHx$WIDTH resizedRibbon.png
  convert ${BASE_IMAGE_PATH} -fill white -font Times-Bold -pointsize 18 -gravity south -annotate 0 "Hello World" - | composite resizedRibbon.png - ${TARGET_PATH}
}

generateIcon "[email protected]"
generateIcon "[email protected]"
generateIcon "AppIcon76x76~ipad.png"
generateIcon "AppIcon76x76@2x~ipad.png"

这会将整个图像处理代码放入一个名为generateIcon()的函数中,并将图标的名称作为参数传递。 该脚本使用$ 1访问此参数,并将其设置为变量BASE_IMAGE_PATH。 $ {BASE_IMAGE_PATH}然后取代[email protected]所在的位置。

您还会注意到一个新的ImageMagick函数,识别并且此函数可以获取有关图像的信息。 在这种情况下,您希望使用通过标识上的-format%w参数获得的宽度来确定如何调整betaRibbon.png的大小。

现在,切换到iPad或iPhone 6+模拟器并运行该项目; 你会在主屏幕上看到修改过的应用程序图标。

你会看到在新设备上,字体大小似乎不一致。 这是因为字体大小以像素表示,并且不同的设备屏幕具有不同的像素密度。
怎样在编译的时候改变你的App图标_第16张图片
有一个简单的解决方案。 你真正想要的只是文本的高度与整个图标的高度成一定比例。

在设置WIDTH变量后立即将以下行添加到脚本中:

FONT_SIZE=$(echo "$WIDTH * .15" | bc -l)

这一行有点棘手,但它的作用是将FONT_SIZE变量设置为WIDTH变量的五分之一。 由于Unix算法不支持浮点运算,因此必须使用bc程序。

基本计算器的缩写,bc可以做浮点计算。 由于它是一个独立的程序,字符串$ WIDTH * .15需要通过管道输入它来执行你想要的。

现在,更改generateIcon()的最后一行以使用FONT_SIZE的值而不是硬编码值18.生成的脚本如下所示:

PATH=${PATH}:/usr/local/bin
IFS=$'\n'

function generateIcon () {
  BASE_IMAGE_NAME=$1
    
  TARGET_PATH="${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/${BASE_IMAGE_NAME}"
  BASE_IMAGE_PATH=$(find ${SRCROOT} -name ${BASE_IMAGE_NAME})
    
  WIDTH=$(identify -format %w ${BASE_IMAGE_PATH})
  FONT_SIZE=$(echo "$WIDTH * .15" | bc -l)

  convert betaRibbon.png -resize $WIDTHx$WIDTH resizedRibbon.png
  convert ${BASE_IMAGE_PATH} -fill white -font Times-Bold -pointsize ${FONT_SIZE} -gravity south -annotate 0 "Hello World" - | composite resizedRibbon.png - ${TARGET_PATH}
}

generateIcon "[email protected]"
generateIcon "[email protected]"
generateIcon "AppIcon76x76~ipad.png"
generateIcon "AppIcon76x76@2x~ipad.png"

在各种设备上运行您的项目,您会发现事情看起来更好。
怎样在编译的时候改变你的App图标_第17张图片

Goodbye World, Hello Build Number

尽管将Hello World文本作为对早期的致敬是很诱人的,但是你想将构建号放在这些图标上,实际上,这是一件非常容易的事情。

内部版本号可以在项目的Info.plist文件中找到CFBundleVersion条目。

那你怎么把它放进你的脚本? 事实证明,你的Mac附带了一个程序来帮助你做到这一点。 它叫做PlistBuddy,你可以在 /usr/libexec/ 中找到它。

将以下行添加到脚本的最顶部:

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")

此行显示如何使用PlistBuddy获取您的内部版本号。 现在只需用$buildNumber替换脚本的“Hello World”部分:

convert ${BASE_IMAGE_PATH} -fill white -font Times-Bold -pointsize ${FONT_SIZE} -gravity south -annotate 0 "$buildNumber" - | composite resizedRibbon.png - ${TARGET_PATH}

在目标设置的General标签中,将您的Build版本号更改为2015
怎样在编译的时候改变你的App图标_第18张图片
现在运行该项目。 您将看到一个带有相应内部版本号的图标:
怎样在编译的时候改变你的App图标_第19张图片

Build Configurations

Cool! 全部的步骤已经完成。 您已经将beta功能区和内部版本号覆盖到应用程序图标,并在每次构建项目时运行。

但不是所有情况都需要bata角标内部构建版本号。 如果你有alpha版本怎么办? 或者更有可能的是,如果您发布版本并拥有版本构建,该怎么办? 你肯定不想把内部版本号放在那上面。

这就是Build Configurations的用武之地。

在Xcode中,转到项目的配置。 默认情况下,您应该看到两种配置:DebugRelease

按+,选择Duplicate Release并将其重命名为Beta。 这将创建一个与Release配置完全相同的新构建配置设置。
怎样在编译的时候改变你的App图标_第20张图片
Debug配置将是alpha / debug版本,Beta配置将是beta版本,Release配置将是应用程序的发行版本。

现在您需要做的就是使用CONFIGURATION构建设置变量将配置提取到脚本中,并在脚本中添加if语句以确定当前配置。 将脚本更新为以下内容:

IFS=$'\n'
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")
versionNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${PROJECT_DIR}/${INFOPLIST_FILE}")
PATH=${PATH}:/usr/local/bin

function generateIcon () {
  BASE_IMAGE_NAME=$1
    
  TARGET_PATH="${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/${BASE_IMAGE_NAME}"
  echo $TARGET_PATH
  echo $SRCROOT
  echo $(find ${SRCROOT} -name "[email protected]")
  BASE_IMAGE_PATH=$(find ${SRCROOT} -name ${BASE_IMAGE_NAME})
  WIDTH=$(identify -format %w ${BASE_IMAGE_PATH})
  FONT_SIZE=$(echo "$WIDTH * .15" | bc -l)
  echo "font size $FONT_SIZE"
    
  if [ "${CONFIGURATION}" == "Debug" ]; then
  convert debugRibbon.png -resize ${WIDTH}x${WIDTH} resizedRibbon.png
  convert ${BASE_IMAGE_PATH} -fill white -font Times-Bold -pointsize ${FONT_SIZE} -gravity south -annotate 0 "$buildNumber" - | composite resizedRibbon.png - ${TARGET_PATH}
  fi
    
  if [ "${CONFIGURATION}" == "Beta" ]; then
  convert betaRibbon.png -resize ${WIDTH}x${WIDTH} resizedRibbon.png
  convert ${BASE_IMAGE_PATH} -fill white -font Times-Boldr -pointsize ${FONT_SIZE} -gravity south -annotate 0 "$buildNumber" - | composite resizedRibbon.png - ${TARGET_PATH}
  fi
}

generateIcon "[email protected]"
generateIcon "[email protected]"
generateIcon "AppIcon76x76~ipad.png"
generateIcon "AppIcon76x76@2x~ipad.png"

你可能感兴趣的:(iOS开发,Xcode,AppIcon)