一个python脚本生成iOS所有尺寸的icon

前言

为 iOS 应用提供 icon 时,我们需要裁剪各种各样的尺寸,目前 Xcode 的 AppIcon 供裁剪的尺寸总共就有 18 个之多。分别是:

iPhone Notification 20 pt 的 2x 和 3x
iPhone Settings 29 pt 的 2x 和 3x
iPhone Spotlight 40 pt 的 2x 和 3x
iPhone App 60 pt 的 2x 和 3x
iPad Notification 20 pt 的 2x 和 3x
iPad Settings 29 pt 的 2x 和 3x
iPad Spotlight 40 pt 的 2x 和 3x
iPad App 60 pt 的 2x 和 3x
iPad Pro App 83.5 pt 的 2x
App Store 的 1024 x 1024

一般来说,只要提供一张 1024 x 1024 的最大尺寸图,然后对该图裁剪成多份尺寸,依次放入 Xcode 里即可。但是这么做很费劲,而且容易出错,像这种工作,交给机器干是再适合不过了。

这里提供一个用 python 脚本自动生成所有 Xcode AppIcon 的方法,不但要求生成所有所需尺寸的图片,并且自动生成对应的配置文件,开发者在运行完脚本后只要直接将指定输出文件拷贝到项目对应目录下即可完成任务。

XCode 中的 Assets 目录及其结构

在 XCode 项目中,有个 Assets 选项,其所在文件夹是一个叫 Assets.xcassets 的目录,该目录下的 AppIcon.appiconset 文件夹是存放应用内 icon 相关信息的地方。

Assets.xcassets 目录内有一个 Contents.json 文件,这个文件用来保存所有 icon 的尺寸和位置信息。它的 json 内容结构示例如下:

{
	"images": [{
		"idiom": "iphone",
		"scale": "2x",
		"size": "20x20",
		"filename": "iphone2x@20x20.png"
	}, ...more ],
	"info": {
		"author": "xcode",
		"version": 1
	}
}

json 字典是由两个键值对组成。

第一个键值对是一个是数组 images,images 的元素中包含着 Xcode 所需的 icon 文件的信息。

键名用途示例
idiomicon 类型iphone, ipad, ios-markiting
scale分辨率倍数2x, 3x
size图片尺寸20x20
filename文件名iphone2x@20x20.png

第二个键值对是额外的字典信息 info,提供了该文件的一些信息(通常不那么重要),可以根据自己需要填写。

键名含义
author作者
version版本号

脚本 icon_generator.py 介绍

icon_generator.py 脚本的作用就是根据用户给定的 icon 文件,生成整个 AppIcon.appiconset 文件夹,并且能保证文件夹内的所有文件符合 xcode 所要求的规范。

安装的软件环境只需要两个:

  1. 编程语言运行环境 Python 3
  2. Python 3 的图形处理库 PIL(也称 Pillow)

脚本名叫 icon_generator.py,通过命令行执行,要求用户提供一个足够大的 png 正方形 icon 图片,这样就 python 脚本负责将这个图片进行处理,生成所需的所有 xcode 所需的 icon 文件,最终生成一个 AppIcon.appiconset 文件夹。命令行示例如下:

python icon_generator.py my_icon.png ./dir

其中,my_icon.png 就是指定的 icon 文件,./dir 是指定一个用于生成结果的目录。

执行完毕后,./dir 目录内将会看到 AppIcon.appiconset 文件夹,我们只要直接将该文件夹拷贝到项目的 Assets.xcassets 即可。

脚本代码:

# using utf-8
import os
import sys
import json
from PIL import Image

JSON_STRING = '''
{
  "images" : [
    {
      "idiom" : "iphone",
      "scale" : "2x",
      "size" : "20x20"
    },
    {
      "idiom" : "iphone",
      "scale" : "3x",
      "size" : "20x20"
    },
    {
      "idiom" : "iphone",
      "scale" : "2x",
      "size" : "29x29"
    },
    {
      "idiom" : "iphone",
      "scale" : "3x",
      "size" : "29x29"
    },
    {
      "idiom" : "iphone",
      "scale" : "2x",
      "size" : "40x40"
    },
    {
      "idiom" : "iphone",
      "scale" : "3x",
      "size" : "40x40"
    },
    {
      "idiom" : "iphone",
      "scale" : "2x",
      "size" : "60x60"
    },
    {
      "idiom" : "iphone",
      "scale" : "3x",
      "size" : "60x60"
    },
    {
      "idiom" : "ipad",
      "scale" : "1x",
      "size" : "20x20"
    },
    {
      "idiom" : "ipad",
      "scale" : "2x",
      "size" : "20x20"
    },
    {
      "idiom" : "ipad",
      "scale" : "1x",
      "size" : "29x29"
    },
    {
      "idiom" : "ipad",
      "scale" : "2x",
      "size" : "29x29"
    },
    {
      "idiom" : "ipad",
      "scale" : "1x",
      "size" : "40x40"
    },
    {
      "idiom" : "ipad",
      "scale" : "2x",
      "size" : "40x40"
    },
    {
      "idiom" : "ipad",
      "scale" : "1x",
      "size" : "76x76"
    },
    {
      "idiom" : "ipad",
      "scale" : "2x",
      "size" : "76x76"
    },
    {
      "idiom" : "ipad",
      "scale" : "2x",
      "size" : "83.5x83.5"
    },
    {
      "idiom" : "ios-marketing",
      "scale" : "1x",
      "size" : "1024x1024"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
'''
ICON_DIR_NAME = "AppIcon.appiconset"
JSON_FILE_NAME = "Contents.json"

if len(sys.argv) < 3 :
    print("argument error.\nexpamle: python icon_generator.py my_icon.png ./dir")
    sys.exit(-1)

input_file = sys.argv[1]
output_dir = sys.argv[2]
// icon_generator.py
dest_dir = os.path.join(output_dir, ICON_DIR_NAME)
json_file_path = os.path.join(dest_dir, JSON_FILE_NAME)

if not os.path.exists(dest_dir):
    os.mkdir(dest_dir)

input_image = Image.open(input_file)
info_map = json.loads(JSON_STRING)
icon_array = info_map["images"]
output_map = info_map
output_map["images"] = []
for icon in icon_array:
    output_icon = icon
    idiom = icon["idiom"]
    scale = icon["scale"]
    size = icon["size"]
    output_width = int(float(size[:size.find("x")]) * float(scale[:scale.find("x")]))
    output_height = output_width
    output_image = input_image.resize((output_width, output_height))
    output_name = idiom + scale + "@" + size + ".png"
    output_path = os.path.join(dest_dir, output_name)
    output_image.save(output_path, "png")
    output_image.close()
    output_icon["filename"] = output_name
    output_map["images"].append(output_icon)

json_file = open(json_file_path, "w")
json_file.write(json.dumps(output_map))
json_file.close()

input_image.close()

移动开发者联盟加入指引

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值