使用
Xcode
,ImageMagick
和shell脚本
, 本教程演示了如何在构建时基于当前构建配置生成应用程序图标, 并可能向您介绍Xcode的一些鲜为人知的功能. 下方示例图片是最终的效果图(在原有的图标上增加了Beta功能区和内部版本号).
您是否相信在本教程中您不会编写任何一行Swift ? 不, 严肃地说, 你也不会写任何Objective-C. :]
本教程将让您只编写bash shell
脚本。 您将使用一个名为ImageMagick
的工具,Terminal
和Xcode
来编写一个脚本,该脚本会自动将构建版本号和“调试”或“测试版”功能区小角标覆盖到应用程序的图标上.
本教程假设您具有Unix脚本
的一些基本知识。 您可以在不成为shell脚本专家的情况下继续学习,但您也可以在Bash初学者指南或高级Bash脚本编制指南中查找所需内容。
所以,你想要开始吗?
首先,您需要安装ImageMagick,这是一个功能强大的图像处理软件套件,并且您只需通过终端就能够与其进行交互。
您可以通过Homebrew很方便地安装ImageMagick.
如果您没有 Homebrew , 或者不知道它是什么, 你可以通过这个工具的主页来了解它, 并学习怎样安装.
如果你已经安装了 Homebrew, 启动终端并输入下面的命令仍然是一个好主意.
brew update
这将确保您获得从Homebrew安装的任何软件都是最新版本。 如果您没有安装Homebrew,它也会通知您。
OK cool, Now, 运行如下的命令:
brew install ImageMagick
您还需要安装软件套件Ghostscript,因为ImageMagick中需要的文本功能依赖于它。 Ghostscript是一个专为渲染PDF和PS文件而设计的软件套件。 你需要它,因为它为ImageMagick提供了字体支持。通过运行如下命令来安装Ghostscript.
brew install ghostscript
如果你稍后遇到任何困难,请运行以下命令:
brew doctor
如果出现任何问题,您将收到有关它的消息,以及如何修复它的说明。
这就是您需要安装才能完成本教程的所有东西。
ImageMagick 有许多命令, 但本教程仅会用到两个 - 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
如果你在屏幕上未看到任何错误, 你将在AppIconSet文件夹中看到一个名为test.png的文件, 并且, 它看起来将会如下图所示:
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没什么区别!
下面是到底发生了什么的分析:
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图像在左上角对齐:
为了使其正常工作,您需要将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,你会看到它现在看起来应该是:
这就是本教程所需的所有ImageMagick功能,但要知道这只是ImageMagick可以做的事情的冰山一角。 查看ImageMagick的主页以了解更多信息。
完成所有图像处理工作后,是时候通过在熟悉的领域工作来清洁您的味觉。
打开Xcode,选择File \ New \ Project …,选择iOS \ Application \ Single View Application模板,然后单击Next。 将项目命名为Llama Trot,将所选语言设置为Swift,并将设备系列设置为Universal。 为简单起见,将项目保存到桌面。
您的目标是在每次构建项目时,让Xcode和ImageMagick生成适当的图标,具体取决于所选的构建配置。
Xcode能够在构建项目时使用运行脚本来执行操作。 运行脚本只是一个Unix脚本,就像您已编写的那样,每次运行Xcode项目时都会执行。
在您的项目中,选择Llama Trot目标,然后导航到Build Phases。 单击+图标,然后从弹出菜单中选择New Run Script Phase:
您将看到运行脚本阶段已添加到项目的阶段。
在该运行脚本中,Shell参数应自动设置为bin / sh
,这意味着该脚本将在bash Unix shell中执行。
shell参数下面是一个框,供您输入脚本。 在该框中键入以下行:
echo "Hello World"
你的新编译阶段应该看起来如下所示:
编译并运行。 你应该看到没什么有趣的。 那是因为脚本在您不看的时候将 Hello World 打印到您的构建日志中。
导航到Report Navigator - 这是Xcode导航器窗格最右侧的图标 - 然后单击最新的构建报告,如下图所示。 在描述Xcode为您构建项目时所做的所有工作的文本墙中,您将看到文本 Hello World:
太棒了,你已经有了一个输出 Hello World 的脚本,就像你在开发人员的职业生涯中这一点可能做了一百万次。 现在是时候修改应用程序图标了。
通过导航到Xcode中的Images.xcassets并将每个图标拖到AppIcon图像集中的相应图块中,将所有应用图标添加到Images.xcassets资产目录:
您还需要将debugRibbon.png和betaRibbon.png放在项目的根目录中 - 与项目的.xcodeproj文件所在的文件夹相同。
为了对图标执行任何操作,您的脚本需要知道它们的位置。 用以下代码替换您的运行脚本:
echo "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
echo "${SRCROOT}"
这可以通过使用Xcode的许多构建设置变量来实现。
运行项目并检查构建报告。 您应该看到描述项目最终产品位置的文件夹路径。 在此之下,您应该看到项目目录的文件夹路径:
(在Finder中)导航到上图打印出的第一条路径并查看其中的内容; 您将看到应用的所有产品,包括所有应用图标。 这是您保存ImageMagick修改的图标的地方。
要查看这些图标,请右键单击该文件夹中的应用程序图标,然后选择显示包内容。 现在看起来很普通!
现在导航到您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]")
顺便说一句,重要的是你输入行IFS = $'\ n'
正好显示 - 在= sign
的两侧没有空格。
运行该项目,您将看到AppIcon60x60 @ 2x的完整路径回显:
艰苦的工作结束了。 现在是时候把所有东西放在一起,让你的脚本正确地修改应用程序图标。 您将从仅修改[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}
这是发生了什么的细分:
PATH
的变量,用于存储默认脚本位置列表。终端在那里首先查找默认情况下不属于Unix的任何命令。这允许位于PATH
目录中的任何命令在不指定命令的完整位置的情况下运行。 Xcode需要与终端共享相同的PATH
变量。此行将/user/local/bin
添加到Homebrew安装其包的PATH
变量中。TARGET_PATH
和BASE_IMAGE_PATH
中;β色带
的尺寸调整到合适的尺寸;pipe into
复合函数(这就是|符号
的作用) , 并将调整大小的beta功能区放在它上面。 ImageMagick使用短划线“ - ”而不是文件名来完成此操作。该脚本将结果保存为产品应用程序图标。**注意:**应用程序图标名称不是任意的。 应用程序图标的名称必须与最终产品中的[email protected]类似。 Xcode使用此命名约定来根据正在使用的设备确定要使用的图标。
运行应用程序并转到设备的主屏幕以查看应用程序的图标; 如果你在模拟器上,按Cmd + Shift + H进入主屏幕。 你应该看到一个修改过的图标:
现在您已经完成了一个图标,现在是时候将脚本概括为适应所有图标,因此可以使用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+模拟器并运行该项目; 你会在主屏幕上看到修改过的应用程序图标。
你会看到在新设备上,字体大小似乎不一致。 这是因为字体大小以像素表示,并且不同的设备屏幕具有不同的像素密度。
有一个简单的解决方案。 你真正想要的只是文本的高度与整个图标的高度成一定比例。
在设置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"
尽管将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:
现在运行该项目。 您将看到一个带有相应内部版本号的图标:
Cool! 全部的步骤已经完成。 您已经将beta功能区和内部版本号覆盖到应用程序图标,并在每次构建项目时运行。
但不是所有情况都需要bata角标
和内部构建版本号
。 如果你有alpha版本怎么办? 或者更有可能的是,如果您发布版本并拥有版本构建,该怎么办? 你肯定不想把内部版本号放在那上面。
这就是Build Configurations的用武之地。
在Xcode中,转到项目的配置。 默认情况下,您应该看到两种配置:Debug和Release。
按+,选择Duplicate Release并将其重命名为Beta。 这将创建一个与Release配置完全相同的新构建配置设置。
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"