Skip to content

Instantly share code, notes, and snippets.

@shnjp
Created December 10, 2013 08:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shnjp/7887290 to your computer and use it in GitHub Desktop.
Save shnjp/7887290 to your computer and use it in GitHub Desktop.
iOS用の画像がどかっと渡された時に、いっぱつでImage.xcassetsを作ってくれるスクリプト
#!/usr/local/bin/python3
# -*- coding:utf-8 -*-
"""
iOS用の画像がどかっと渡された時に、いっぱつでImage.xcassetsを作ってくれるスクリプ
python3 yorosikuimage [画像のディレクトリ] [Image.xcassetsのパス]
"""
from PIL import Image
import os
import json
import shutil
from collections import namedtuple
IconSpec = namedtuple('IconSpec', 'size scale idiom')
APPICON_SPECS = [
IconSpec((60, 60), '2x', 'iphone'),
IconSpec((57, 57), '1x', 'iphone'),
IconSpec((57, 57), '2x', 'iphone'),
IconSpec((72, 72), '1x', 'ipad'),
IconSpec((72, 72), '2x', 'ipad'),
IconSpec((76, 76), '1x', 'ipad'),
IconSpec((76, 76), '2x', 'ipad'),
IconSpec((29, 29), '1x', 'iphone'),
IconSpec((29, 29), '2x', 'iphone'),
IconSpec((40, 40), '2x', 'iphone'),
IconSpec((50, 50), '1x', 'ipad'),
IconSpec((50, 50), '2x', 'ipad'),
IconSpec((40, 40), '1x', 'ipad'),
IconSpec((40, 40), '2x', 'ipad'),
IconSpec((29, 29), '1x', 'ipad'),
IconSpec((29, 29), '2x', 'ipad'),
]
LaunchImageSpec = namedtuple('LaunchImageSpec', 'size scale orientation subtype minimum_system_version idiom extent')
LAUNCHIMAGE_SPECS = [
LaunchImageSpec((320, 480), '1x', 'portrait', None, None, 'iphone', None),
LaunchImageSpec((640, 960), '2x', 'portrait', None, None, 'iphone', None),
LaunchImageSpec((640, 1136), '2x', 'portrait', 'retina4', None, 'iphone', None),
LaunchImageSpec((640, 960), '2x', 'portrait', None, '7.0', 'iphone', None),
LaunchImageSpec((640, 1136), '2x', 'portrait', 'retina4', '7.0', 'iphone', None),
LaunchImageSpec((768, 1004), '1x', 'portrait', None, None, 'ipad', 'to-status-bar'),
LaunchImageSpec((1536, 2008), '2x', 'portrait', None, None, 'ipad', 'to-status-bar'),
LaunchImageSpec((1024, 748), '1x', 'landscape', None, None, 'ipad', 'to-status-bar'),
LaunchImageSpec((2048, 1496), '2x', 'landscape', None, None, 'ipad', 'to-status-bar'),
LaunchImageSpec((768, 1024), '1x', 'portrait', None, '7.0', 'ipad', 'full-screen'),
LaunchImageSpec((1536, 2048), '2x', 'portrait', None, '7.0', 'ipad', 'full-screen'),
LaunchImageSpec((1024, 768), '1x', 'landscape', None, '7.0', 'ipad', 'full-screen'),
LaunchImageSpec((2048, 1536), '2x', 'landscape', None, '7.0', 'ipad', 'full-screen'),
]
def main():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('from_dir', metavar='FROM_DIR')
parser.add_argument('output_path', metavar='OUTPUT_PATH')
args = parser.parse_args()
images = enum_images(args.from_dir)
# ベタ書き
output_path = args.output_path
if not output_path.endswith('.xcassets'):
output_path = output_path + '.xcassets'
if not os.path.isdir(output_path):
os.makedirs(output_path)
make_app_icon_asset(output_path, 'AppIcon', images)
make_launch_image_asset(output_path, 'LaunchImage', images)
def enum_images(from_dir):
images = {}
for path, dirs, files in os.walk(from_dir):
for filename in files:
ext = os.path.splitext(filename)[1]
if ext not in ('.jpg', '.jpeg', '.png'):
continue
filepath = os.path.join(path, filename)
im = Image.open(filepath)
images[im.size] = filepath
return images
def make_app_icon_asset(assets_path, setname, images):
set_path = os.path.join(assets_path, '{}.appiconset'.format(setname))
if os.path.exists(set_path):
shutil.rmtree(set_path)
os.makedirs(set_path)
# find source image
try:
source_path = images[(2048, 2048)]
except:
print('iTunes size AppIcon not found')
source_im = Image.open(source_path)
images = []
for spec in APPICON_SPECS:
assert(spec.size[0] == spec.size[1])
assert(spec.scale in ('1x', '2x'))
size = spec.size[0] * (2 if spec.scale == '2x' else 1)
# save resized image
resized = source_im.resize((size, size))
icon_file_name = '{}_{}'.format(setname, spec.size[0])
if spec.scale != '1x':
icon_file_name += '@' + spec.scale
icon_file_name += '.png'
resized.save(os.path.join(set_path, icon_file_name), 'PNG')
# add icon to images
images.append({
'idiom': spec.idiom,
'scale': spec.scale,
'size': '{}x{}'.format(*spec.size),
'filename': icon_file_name
})
contents = {
'images': images,
'info' : {
'version' : 1,
'author' : 'xcode'
}
}
with open(os.path.join(set_path, 'Contents.json'), 'w', encoding='utf8') as fp:
json.dump(contents, fp, sort_keys=True, indent=2)
def make_launch_image_asset(assets_path, setname, images):
set_path = os.path.join(assets_path, '{}.launchimage'.format(setname))
if os.path.exists(set_path):
shutil.rmtree(set_path)
os.makedirs(set_path)
contents_images = []
for spec in LAUNCHIMAGE_SPECS:
assert(spec.scale in ('1x', '2x'))
d = {
'idiom': spec.idiom,
'scale': spec.scale,
'orientation': spec.orientation,
}
if spec.subtype:
d['subtype'] = spec.subtype
if spec.extent:
d['extent'] = spec.extent
if spec.minimum_system_version:
d['minimum-system-version'] = spec.minimum_system_version
if spec.size in images:
subtype = ''
suffix = ''
if spec.idiom == 'iphone' and spec.subtype == 'retina4':
subtype = '-568h'
elif spec.idiom == 'ipad':
if spec.orientation == 'portrait':
subtype = '-Portrait'
else:
subtype = '-Landscape'
if spec.extent == 'to-status-bar':
suffix = '_tsb'
image_file_name = 'Default{suffix}{subtype}{scale}~{device}.png'.format(
subtype=subtype,
scale=('' if spec.scale == '1x' else '@' + spec.scale),
device=spec.idiom,
suffix=suffix
)
d['filename'] = image_file_name
dst_path = os.path.join(set_path, image_file_name)
shutil.copyfile(images[spec.size], dst_path)
contents_images.append(d)
contents = {
'images': contents_images,
'info' : {
'version' : 1,
'author' : 'xcode'
}
}
with open(os.path.join(set_path, 'Contents.json'), 'w', encoding='utf8') as fp:
json.dump(contents, fp, sort_keys=True, indent=2)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment