iOS图标自动化生成:一张1024主图搞定全尺寸App Icon

发布时间:2026/10/24 3:33:35
iOS图标自动化生成:一张1024主图搞定全尺寸App Icon

做iOS开发这几年,我最不想碰的活儿就是“切图标”。一张设计稿,按苹果的规格表手动导出十几个尺寸,从20像素的通知栏小图到1024像素的商店大图,中间还分iPhone和iPad两套,命名不能乱、透明通道不能有、圆角不能自己加,稍不留神就被审核打回来。后来我换了个思路:只维护一张1024像素的正方形主图,剩下所有尺寸全部交给自动化工具体系批量生成,顺便把Xcode资产目录需要的配置文件也写好,整个过程几分钟就完事。今天这篇就围绕“一张图生成iOS应用Icon各种尺寸”这个主题,把工具选型、实操流程和那些文档里不会写的坑一次讲清楚。这篇文章适合独立开发者,也适合团队里负责打包的同事直接拿去套用。

1. 先把iOS图标规格表吃透,才知道工具该生成哪些尺寸

很多教程上来就让你“找个工具生成”,但如果你自己都不知道要生成哪些尺寸,拿到工具一样会出问题。我建议先花两分钟把规格表过一遍,这样后面玩任何工具心里都有底。

1.1 iPhone、iPad全量尺寸清单

iOS图标的规格体系可以拆成三块:iPhone、iPad、App Store(商店展示)。每一块里又按“逻辑尺寸 × 倍率”得到实际像素。逻辑尺寸的单位是pt,倍率是@1x/@2x/@3x,两者相乘才是最终图片的像素尺寸。很多新手直接把逻辑尺寸当像素去切图,这里必须先纠正。

平台逻辑尺寸倍率实际像素用途
iPhone20x20@2x / @3x40 / 60通知栏、设置列表
iPhone29x29@2x / @3x58 / 87设置、搜索
iPhone40x40@2x / @3x80 / 120主屏幕、搜索
iPhone60x60@2x / @3x120 / 180主屏幕
iPad20x20@1x / @2x20 / 40通知栏
iPad29x29@1x / @2x29 / 58设置
iPad40x40@1x / @2x40 / 80主屏幕
iPad76x76@1x / @2x76 / 152主屏幕
iPad Pro83.5x83.5@2x167主屏幕
App Store1024x1024@1x1024商店展示

合计下来,一套Universal(iPhone + iPad + App Store)图标通常需要18个PNG文件。注意83.5x83.5这个逻辑尺寸是带小数点的,实际像素是167而不是168,很多工具在这个数字上做过翻转,如果你手工切图,这里特别容易写错文件名或算错像素。

1.2 为什么“一张大图”不能直接传

可能有人会问:系统不会自己缩放吗?为什么非要我交这么多尺寸?原因是iOS在渲染图标时是按固定像素读取对应文件的,通知栏读的是20pt那一档,主屏幕读的是60pt或76pt那一档,资产目录里没有对应文件,系统就会给你渲染出一个默认占位图,丑且不可控。

Xcode提供了“Single Size”选项,可以只放一张1024大图,让Xcode在构建时自动生成其余尺寸。这个功能对快速验证很友好,但有两个问题:一是App Store上传时仍然需要单独提供1024图标,二是构建阶段的自动缩放你没机会手动干预,万一某档尺寸效果不理想也没法单独替换。所以现在的正式项目里,大多数人还是选择一次性生成全套PNG,明确可控,也和团队里的设计流程更好配合。

我自己走“一张主图 + 批处理工具”的路线,本质上把“维护”这件事收敛到一张源图上:改设计只改这一张,重跑一遍脚本,所有尺寸同步更新,不会出现“改了主图忘记重新导出小图”这种事故。

2. 生成工具的三种思路,按场景选

2.1 在线生成器:胜在快,但别随便传图

现在很多在线工具站都支持“上传一张图,自动生成全套Icon”,对个人项目或者Demo来说非常方便:打开网页、拖图进去、下载zip,几秒钟搞定。我最早也是这么干过来的,省事是真省事。

但用这类工具要谨慎几点。第一是隐私,正式项目的设计稿在没发布之前属于内部资产,传到第三方服务器有一定风险,公司项目或者有保密协议的项目我不建议用。第二是质量,我实测过多个在线生成器,有的输出1024图带透明通道,有的文件名和标准不一致,还有的在小尺寸上处理得特别糊,你下载完必须逐个检查。第三是可用性,一旦在离线环境或者内网开发,这类工具直接废掉。

2.2 设计软件插件的导出预设

如果你平时就是用设计软件画图标,更好的思路是在里面建立导出预设,需要切图时一键导出全部尺寸。好处是源图是矢量的,导出清晰度有保障,而且和设计流程无缝衔接,设计师自己就能搞定,不用每次找开发。

缺点是依赖设计工具环境,团队里不是每个人都有这个软件;另外每次都要人工触发导出,自动化程度还是差一口气。如果你是一个人在维护全流程,脚本方案会更省心。

2.3 脚本批处理:我最推荐的长期方案

我最推荐的是脚本方式:Python + 图像处理库(Pillow)写一个独立脚本,放在项目仓库里。跑一次就生成全部尺寸,自动写Contents.json,顺便检查每张图的尺寸和透明通道,全程不需要打开任何图形界面。

为什么脚本方案长期用下来最舒服?因为它是可复现、可验证、可继承的。新建项目时把脚本复制过去,改一下源图路径就能用;CI里也能挂一道校验,谁改了图标尺寸不对直接报错。在线工具做不到这些,设计插件也做不到全自动。下面我就把完整脚本和用法展开讲。

3. 一张1024主图生成全套Icon的完整实操

3.1 源图准备的三个硬性要求

源图质量决定了全套成品的质量,这一步千万别省。我的要求就三条:

第一,必须是无透明通道的1024x1024正方形PNG或JPEG。如果你是从设计软件导出源文件,务必确认最终导出的图不带alpha通道,原因后面会专门说。

第二,不要预先加圆角。iOS系统会自动给图标套一层圆角遮罩,如果你自己把角切圆了,最终显示会是“圆角里套圆角”,四角还会露出背景色,非常难看。老老实实给满幅正方形即可。

第三,核心内容要居中并留出安全边距。苹果官方的建议是图标四周大约有10%的区域会在裁切和圆角遮罩中损失掉,所以重要内容最好控制在中央约80%的区域内。很多新人把图形画满全幅,结果小尺寸下边缘被切得七零八落。文件名也顺手规范一下:不要用中文、不要带空格,全小写加连字符最稳。

3.2 批处理脚本的完整实现

脚本逻辑并不复杂:读入主图,按规格表逐项缩放,保存PNG,最后生成一份Contents.json。下面是我在项目里实际用的版本,你复制到本地、装好Pillow就能跑。

pip install pillow
#!/usr/bin/env python3 import os import json from PIL import Image SRC = "master_1024.png" OUT = "AppIcon.appiconset" # (逻辑尺寸, 倍率, 设备平台, 输出文件名) SPECS = [ # iPhone ("20x20", "2x", "iphone", "Icon-iphone-20@2x.png"), ("20x20", "3x", "iphone", "Icon-iphone-20@3x.png"), ("29x29", "2x", "iphone", "Icon-iphone-29@2x.png"), ("29x29", "3x", "iphone", "Icon-iphone-29@3x.png"), ("40x40", "2x", "iphone", "Icon-iphone-40@2x.png"), ("40x40", "3x", "iphone", "Icon-iphone-40@3x.png"), ("60x60", "2x", "iphone", "Icon-iphone-60@2x.png"), ("60x60", "3x", "iphone", "Icon-iphone-60@3x.png"), # iPad ("20x20", "1x", "ipad", "Icon-ipad-20@1x.png"), ("20x20", "2x", "ipad", "Icon-ipad-20@2x.png"), ("29x29", "1x", "ipad", "Icon-ipad-29@1x.png"), ("29x29", "2x", "ipad", "Icon-ipad-29@2x.png"), ("40x40", "1x", "ipad", "Icon-ipad-40@1x.png"), ("40x40", "2x", "ipad", "Icon-ipad-40@2x.png"), ("76x76", "1x", "ipad", "Icon-ipad-76@1x.png"), ("76x76", "2x", "ipad", "Icon-ipad-76@2x.png"), ("83.5x83.5", "2x", "ipad", "Icon-ipad-83.5@2x.png"), # App Store ("1024x1024", "1x", "ios-marketing", "Icon-1024.png"), ] PIXELS = { "20x20": 20, "29x29": 29, "40x40": 40, "60x60": 60, "76x76": 76, "83.5x83.5": 83.5, "1024x1024": 1024, } SCALES = {"1x": 1, "2x": 2, "3x": 3} os.makedirs(OUT, exist_ok=True) img = Image.open(SRC) # 关键:压平透明通道,避免生成带alpha的PNG if img.mode == "RGBA": background = Image.new("RGB", img.size, (255, 255, 255)) background.paste(img, mask=img.split()[3]) img = background.convert("RGB") for size, scale, idiom, filename in SPECS: px = int(round(PIXELS[size] * SCALES[scale])) resized = img.resize((px, px), Image.LANCZOS) resized.save(os.path.join(OUT, filename)) # 生成 Contents.json images = [] for size, scale, idiom, filename in SPECS: images.append({ "filename": filename, "idiom": idiom, "scale": scale, "size": size, }) contents = {"images": images, "info": {"author": "xcode", "version": 1}} with open(os.path.join(OUT, "Contents.json"), "w", encoding="utf-8") as f: json.dump(contents, f, indent=2, ensure_ascii=False) print(f"已生成 {len(images)} 张图标到 {OUT}/")

代码里有两个细节值得说明。一是用了Image.LANCZOS作为缩放算法,这是图像处理库中质量较高的下采样算法,从1024缩到20像素这种大倍率缩放,它能最大程度保留边缘细节;如果用默认的最近邻算法,小尺寸会出现明显锯齿。二是做了RGBA到RGB的铺底处理,把透明区域用白色背景压平再缩放,防止生成的PNG残留alpha通道,这一步对审核非常重要。

3.3 生成Contents.json并接入Xcode

Contents.json是Xcode资产目录的“说明书”,每条记录把文件名与设备类型、逻辑尺寸、倍率对应起来。Xcode读到这份文件后,就知道该往哪个设备放哪个图标。脚本已经把它一并生成好了,使用方式如下:

  1. 在Xcode中打开Assets.xcassets,找到AppIcon;如果工程模板里没有,就新建一个AppIcon。
  2. 选中AppIcon后,把脚本生成的AppIcon.appiconset文件夹里的全部文件(包括Contents.json)拖进去覆盖。
  3. 在TARGETS的General页签下,确认App Icon Source指向当前这个AppIcon即可。

如果你不想用脚本,也可以直接在Xcode里把资产目录的图标位一张张拖图填充,但那个操作极其繁琐,我手动拖过一次之后就没再尝试第二次了。脚本一步到位,而且是确定性输出,同一个源图每次生成结果完全一致,这在工作交接时特别有价值。

4. 生成之后最容易踩的五个坑

4.1 alpha通道:App Store审核的高频拒因

我真实遇过:图标一切正常,提交App Store后收到反馈说“图标不能包含透明通道”。排查半天,根源是一张带alpha通道的源图被在线工具改成了PNG输出,缩小时的透明边缘也一起留了下来。

解决方案就是脚本里那段RGBA转RGB逻辑,把透明区域用白色背景铺底。你可以用macOS自带命令检查一张PNG是否残留透明通道:

sips -g hasAlpha Icon-1024.png

输出yes就说明还有透明通道,必须重新铺底处理。我建议把这步做成强制校验,输出后全部为no再往上传。

4.2 圆角:千万别自己加

这个和源图准备里说的一样,我再强调一次。很多设计同学习惯在导出时顺手加个圆角,觉得“图标本来就是圆的嘛”。但iOS是通过系统级遮罩统一处理圆角的,你提前加了圆角,真机上就是双重圆角,而且圆角外区域会露出你填的背景色或透明,观感很差。源图永远是满幅正方形,剩下的交给系统。

4.3 83.5这个奇葩尺寸

83.5x83.5是iPad Pro主屏幕图标专属逻辑尺寸,@2x后是167像素。它是半整数,手工计算时极容易出错,常见错误是算成168或者干脆漏掉这个尺寸。脚本里用round()处理像素整数化,既不会出现浮点尺寸,也不会四舍五入错位,这就是我坚持用脚本的重要原因之一。

4.4 小尺寸图标模糊

1024缩到20像素,信息量损失巨大。如果你的原图细节过多,20像素下会糊成一团。经验做法是:为主图准备两个层级,大尺寸用复杂原图,小尺寸尽量用粗线条、大色块、高对比的图形。做不到的话,至少确保主图核心图形在缩小之后仍然可辨认,细节别堆太满。我在一个项目里就吃过亏,原图是一条很精致的渐变线条龙,60像素下还好,20像素下完全成了一坨灰,最后重新设计了一套简化版才解决问题。

4.5 Contents.json写错

手写Contents.json最容易错的地方是idiom、size、scale三个字段的对应关系,比如把iPhone的尺寸标成ipad,或者把scale写反。Xcode加载时会提示“不完整”或警告,App Store审核甚至可能匹配错图标。用脚本自动生成能完全规避这类问题,因为规格表是程序里固化的,不会出现人为笔误。

下面对应关系做个速查表,方便你排查:

症状常见原因解决办法
审核提示图标带透明通道源图或输出PNG含alpha脚本RGBA转RGB,或用sips检查
真机图标圆角处露白边源图预加了圆角重新导出满幅正方形
iPad Pro图标缺失或错位漏了83.5逻辑尺寸用规格表核对是否生成167像素
小尺寸图标成一团糊原图细节太多简化图形或准备两套主图
Xcode提示图标不完整Contents.json字段写错改用脚本自动生成JSON

5. 一些实战心得与进阶技巧

5.1 加一个校验脚本兜底

批处理脚本生成完,我还会跑一个校验脚本,把每个文件的尺寸、透明通道、命名全部检查一遍。简化版如下:

import os from PIL import Image DIR = "AppIcon.appiconset" EXPECTED = { "Icon-iphone-20@2x.png": 40, "Icon-iphone-20@3x.png": 60, # ... 按规格表补全 } for name, px in EXPECTED.items(): path = os.path.join(DIR, name) if not os.path.exists(path): print(f"缺少文件: {name}") continue im = Image.open(path) if im.size != (px, px): print(f"尺寸错误: {name} 应为 {px}x{px}, 实际 {im.size[0]}x{im.size[1]}") if im.mode == "RGBA": print(f"含透明通道: {name}")

这个校验脚本可以作为CI的一个检查步骤,谁改动图标提交代码,只要不通过就挡住,省心很多。

5.2 多项目复用的正确姿势

我的做法是把生成脚本放在一个公共工具仓库里,用命令行参数指定源图路径和输出目录。新项目要接图标时,一行命令就能完成生成和校验。整个流程从“手动切图半小时”缩短到“跑脚本两分钟”,而且不再需要对着苹果规格表查来查去。

5.3 别忘了真机预览

最后提醒一个容易被忽略的步骤:生成的图标一定要在真机上跑一遍,重点看主屏幕图标和设置页图标。模拟器里有些渲染差异,真机上才能看出小尺寸的清晰度和圆角遮罩效果。我通常在开发机上连一台真机,装上测试包,把主屏幕和设置页都滑一遍,没问题再提交。

这套流程我现在已经用在了好几个项目上,最大的感受就是“心里有底”。以前每次发版都担心图标哪个尺寸漏了,现在源图更新一条命令搞定,校验脚本再兜底一道,审核那边再没因为图标被退回过。如果你还在手动切图,强烈建议把这套工具链一次性搭起来,省下来的时间足够你多测几个真机页面了。