为什么图标永远是"最后 5% 里的 95% 工作量"
做过独立项目的人都懂:功能写完了,壳也套好了,结果卡在图标上——
- 找设计师:一套品牌图标报价几百到几千,还得排期、来回改稿;
- 自己用 Figma 画:没有美术功底,画出来像表情包;
- 用通用 AI 生图工具(Midjourney、各种文生图):出图是好看,但它是一张 1024 的"图片",不是"图标资产"——没有 iOS 要的 AppIcon.appiconset,没有 Android 的 mipmap 各密度目录,上架的时候还是得自己一张张切。
这篇文章记录我现在的做法:AI 生成 + 一次导出全套平台尺寸,整个链路十分钟以内。先把规范讲清楚(这是踩坑重灾区),再看工作流。
一、先搞清楚各平台到底要什么
iOS:无透明、无圆角、单一 1024 时代
Xcode 14 之后,asset catalog 支持"单尺寸"模式——你只需要提供一张 1024×1024 的 PNG,其余尺寸由 Xcode 自动生成。但有三条红线,年年都有人踩:
- 不能带 alpha 通道。带透明通道上传会被 App Store Connect 拒掉,报错
ITMS-90717: Invalid App Store Icon。用 ImageMagick 一条命令可以检查并去除:convert icon.png -alpha off icon.png。 - 不要自己切圆角。iOS 会根据系统遮罩自动裁圆角,你预切了圆角,上架后边缘就是一圈白边/透明边。
- 扁平化、不透明背景。渐变可以有,透明不行。
如果项目还要兼容旧工具链,传统的 AppIcon.appiconset 全家桶长这样(也是自动导出工具生成的标准结构):
| 尺寸(pt) | @1x | @2x | @3x | 用途(idiom) |
|---|---|---|---|---|
| 20 | 20px | 40px | 60px | iPhone 通知栏 / iPad 设置 |
| 29 | 29px | 58px | 87px | 设置页 |
| 40 | 40px | 80px | 120px | 通知中心 / Spotlight |
| 60 | — | 120px | 180px | 主屏幕 |
| 76 | 76px | 152px | — | iPad 主屏幕 |
| 83.5 | — | 167px | — | iPad Pro 主屏幕 |
| 1024 | 1024px | — | — | App Store 营销图 |
Android:不只是切尺寸,还有"分层"这件事
传统启动器图标按屏幕密度出五档:
| 密度 | 像素 |
|---|---|
| mdpi | 48×48 |
| hdpi | 72×72 |
| xhdpi | 96×96 |
| xxhdpi | 144×144 |
| xxxhdpi | 192×192 |
但 Android 8.0 之后的正解是自适应图标(Adaptive Icon),它的结构和 iOS 完全不同:
- 画布是 108×108 dp,前景层和背景层各一张;
- 系统只显示中心约 72dp 的区域,重要内容必须收在中心 66dp 安全区内——不然 launcher 换个圆形蒙版,你的 logo 就被裁掉一角;
- 不同厂商 launcher 蒙版不同(圆、圆角方、水滴……),分层就是为了让你不用为每种形状单独出图;
- xxxhdpi 下每层是 432×432 px;
- 另外 Google Play 商店列表还需要一张独立的 512×512 PNG。
这就是为什么"拿一张图直接缩放"在 Android 上行不通——你需要的是前景/背景两张图层 + 一份 adaptive-icon XML,而不是一张方图。
Web / PWA:别漏了 maskable
| 文件 | 尺寸 | 说明 |
|---|---|---|
| favicon | 16 / 32 / 48 | 浏览器标签页 |
| apple-touch-icon | 180×180 | iOS 添加到主屏幕 |
| PWA icon | 192 / 512 | manifest.json 必备 |
| maskable 变体 | 192 / 512 | 全出血版,PWA 装进安卓启动器用 |
maskable 图标的关键是安全区:所有平台保证可见的只有中心 直径 80% 的圆形区域,背景必须不透明。做法上建议 any 和 maskable 各出一套,而不是一张图标两个用途混用——带留白的 maskable 图在不需要蒙版的场合会显得特别小。
Lighthouse 有专门的 maskable-icon 审计项,缺了它 PWA 评分直接掉一截。
二、实战:从一句话到全套资产
规范清楚了,接下来是生成环节。我现在用的流程是这样的(工具叫 AppIconKitchen):
1. 用一句话描述你的应用
不需要写很长的咒语,一个明确的视觉主体 + 简单背景就够了,比如:
一只白色蓬松的云朵,蓝色渐变背景
几个实战 prompt 技巧:
- 一个图标只放一个主体。小尺寸下(48px 的 mipmap)细节全糊掉,主体越简单辨识度越高;
- 让 AI 出"图标",而不是"插画"。加 style 类关键词(3D clay、flat、glassmorphism 等)比描述"精美、大师级"有效得多;
- 别让 AI 画文字。目前图像模型生成文字还是容易乱码,图标里带字母是高风险操作;
- 中文描述完全没问题,模型对语义的理解不看语言。
2. 选风格 + 配色 + 容器形状
风格预设我一般在这几档里选:
- 3D Clay:黏土质感,可爱系 App 万金油;
- Flat / Minimal Flat:工具类、效率类 App 首选,耐看;
- Glassmorphism:毛玻璃质感,适合 "高级感" 定位的产品;
- Pixel Art:游戏和复古主题;
- Mac Style / Neon Glow:桌面工具 / 夜间系产品。
配色上,自定义一个品牌主色通常比默认色板效果好——背景色和前景主体的对比度直接决定图标在深色壁纸下的可见度。容器形状(square / squircle / rounded-square / circle)建议保守选 squircle 或 rounded-square,和两家系统默认观感最接近。
3. 一次生成多张候选,再"精修"
一次出 4 张候选对比着选,比一次一张反复重roll 效率高得多——同参数下 4 张里总有一张构图是对的。
选完之后的重点功能是自然语言精修:基于当前这张图继续改,而不是重新画。比如:
主体图形缩小 20% 云朵再蓬松一点,背景渐变加深
每轮修改会存成一个版本,可以随时切回任意历史版本。这解决了 AI 生成最大的痛点——"改一个地方,其他全变了"。
4. 导出
确认效果后一键导出 ZIP,里面是直接可用的工程结构,不用再手动整理:
appicon-export.zip
├── ios/
│ └── AppIcon.appiconset/ # 20~1024 全部尺寸 + Contents.json
│ # Xcode 里整个文件夹拖进 asset catalog 即可
├── android/
│ ├── mipmap-{mdpi..xxxhdpi}/ # 传统 5 档密度
│ ├── mipmap-*_adaptive/ # 自适应图标前景/背景层 + XML
│ └── playstore-icon.png # 512×512 商店图
├── web/
│ ├── favicon-*.png # 16/32/48
│ ├── apple-touch-icon.png # 180
│ ├── icon-{192,512}*.png # 含 maskable 变体
│ └── manifest.json # 现成的 PWA 图标声明
└── expo/ # Expo 项目专用的资产包 + app.json 示例
Flutter 用户把 ios/ 和 android/ 里的产物分别放进 ios/Runner/Assets.xcassets 和 android/app/src/main/res 就完事;Expo 用户更省事,直接用现成的 expo 包。
三、写在最后
总结一下这套流程的核心价值:AI 负责出图,工程化导出负责"能上架"。通用生图工具止步于前者,而开发者真正缺的是后者——一张好看的图和一套能提交商店的资产之间,隔着一整个 exportConfigs。