如何更换 App icon
每逢重大节日,App icon 就要跟一波“潮流”做一次更换,节日过后再换回普通。如何保证这两次切换流程丝滑顺畅呢?
应用内需要更换的 icon 包括两处,一个是 App 主 icon,默认放在 xcassets 里面,另一个就是 App 内部页面所使用的 icon。
App 主 icon 更换
苹果这边需要的 icon 实在太多了,如果像我们 App 一样支持 iPad 那么大大小小的 icon 就需要 18 张,就算让设计师同学给到所有需要的尺寸我们自己在 .xcassets 一一对应起来也是超级麻烦,如果我们只需要提供一张高清图(1024x1024 pixel)剩下的能通过工具自动对应起来该多好啊!
研究xcassets结构后发现,AppIcon 类型的图片是一个后缀名为 appiconset 的文件夹,该文件夹里面除了有 APP 需要的各种尺寸的 png 图片外,还有一个 Contents.json 文件,形如:
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "IOS_40-2.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "IOS_167.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "IOS_1024.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
描述了了各种尺寸的图片如何与文件夹中的 png 图片对应,我们按照此规律便可以写一个更换 AppIcon 的工具。
之前确实听说过有自动生成这种 icon 的工具 App 但我没有使用过,要为如此一个小功能下载一个 App 我觉得太不环保了。还是自己写一个脚本实现比较低碳。下面是 python 程序和注释
# !/usr/local/bin/python3
# _*_ coding:utf-8 _*_
__doc__="""
输入:一个 1024*1024 的 png 图片
输出: AppIconxxxxx.appiconset 目录,包含 iPhone 和 iPad 所需的 App Icons
"""
import os,sys
import imghdr
import json
import random,shutil
from PIL import Image,ImageFile
class FileSet:
def __init__(self,filename,scale):
self.filename = filename
self.scale = scale
@classmethod
def fileset(cls,scale,size,prefix):
filename = "{}.{}.{}.png".format(size,scale,prefix)
file_set = FileSet(filename,scale)
return file_set
class ImageSet:
def __init__(self,size,idiom,filesets):
self.size = size # 单边
self.idiom = idiom
self.filesets = filesets # 数组,包含文件名,一个 size 可能有多个 scale,所有会有多个文件 set
def json_desc(self):
descs = []
for fileset in self.filesets:
json_dict = {"size":"{}x{}".format(self.size,self.size),
"idiom":self.idiom,
"filename":fileset.filename,
"scale":"{}x".format(fileset.scale)}
descs.append(json_dict)
return descs
@classmethod
def iPhone_set(cls,size,filesets):
return ImageSet(size,'iphone',filesets)
@classmethod
def iPad_set(cls,size,filesets):
return ImageSet(size,'ipad',filesets)
@classmethod
def market_set(cls,file_prefix=''):
size = 1024
return ImageSet(size,idiom='ios-marketing',filesets=[FileSet.fileset(1,size,file_prefix)])
def get_img_sets(iPad=False,iPhone=False,file_prefix=''):
img_sets = []
if iPad:
for size in [20,29,40,76]:
file_sets = [FileSet.fileset(2,size,file_prefix),FileSet.fileset(1,size,file_prefix)]
one_set = ImageSet.iPad_set(size,file_sets)
img_sets.append(one_set)
img_sets.append(ImageSet.iPad_set(83.5,[FileSet.fileset(2,83.5,file_prefix)]))
if iPhone:
for size in [20,29,40,60]:
file_sets = [FileSet.fileset(2,size,file_prefix),FileSet.fileset(3,size,file_prefix)]
one_set = ImageSet.iPhone_set(size,file_sets)
img_sets.append(one_set)
img_sets.append(ImageSet.market_set(file_prefix))
return img_sets
def create_appicon_set(imgobj,t_path='',iPad=False,iPhone=True):
rand_str = str(random.randint(20000,2147483648))
t_folder_path = os.path.join(t_path,"AppIcon"+ rand_str +".appiconset")
os.makedirs(t_folder_path)
img_sets = get_img_sets(iPad=iPad,iPhone=iPhone,file_prefix=rand_str)
contents = {"info":{"version":1,"author":"xcode"}}
images = []
for single_set in img_sets:
for fileset in single_set.filesets:
scale_size = (int(single_set.size * fileset.scale), int(single_set.size * fileset.scale))
img_obj = imgobj.resize(scale_size,Image.ANTIALIAS)
real_path = os.path.join(t_folder_path,fileset.filename)
img_obj.save(real_path)
print("保存文件{},\t路径:{}".format(scale_size,real_path))
images += single_set.json_desc()
contents["images"] = images
with open(os.path.join(t_folder_path,"Contents.json"),"w") as wf:
wf.write(json.dumps(contents,indent=4))
if __name__ == '__main__':
argvs = sys.argv[1:] if len(sys.argv) == 3 else None
if not argvs:
print("Fatal: 要求两个参数,第一个是图片路径,第二个是目标目录")
sys.exit(-1)
o_img_path,t_path = argvs
if not os.path.isfile(o_img_path) or not imghdr.what(o_img_path) in ['png']:
print("Fatal: 图片路径不存在或者非 png 格式图片")
sys.exit(-1)
if not os.path.isdir(t_path):
print("Fatal: 目标路径不存在或者非目录")
sys.exit(-1)
o_img = Image.open(o_img_path)
if (1024,1024) != o_img.size :
print("Fatal: 图片非 1024x1024 pixel 尺寸")
sys.exit(-1)
"""
碰到设计师犯糊,将肉眼看不见但确实带有 Alpha 通道的图片提供给我们,直到我们在提交 App Store 的那一刻苹果报错说带有 Alpha 通道,然后我们又要重新走一遍流程
如何更换 App icon的更多相关文章
- 【转】【iOS】动态更换App图标
原文网址:http://www.cocoachina.com/ios/20170619/19557.html 前言 动态更换App图标这件事,在用户里总是存在需求的:有些用户喜欢“美化”自己的手机.至 ...
- 在设置app icon时的问题
APP 运行时遇到 the app icon set named appicon did not have any applicable content 是应该考虑是icon可能偏大
- [摘抄]iOS App icon、启动页、图标规范
以下内容都是我在做App时通过自己的经验和精品的分析得来的,希望会帮助到你.但是有时个别情况也要个别分析,要活学活用. 一. App Icon 在设计iOS App Icon时,设计师不需要切圆角, ...
- [iOS]The app icon set named "AppIcon" did not have any applicable content.
Develop Tools: xCode 5.1 I write a demo for app settings feature. The tutorial url is here. When I a ...
- App Icon生成工具(转载)
原地址:http://www.cocoachina.com/bbs/read.php?tid=290247 下载软件:在AppStore搜索App Icon Gear 打开软件 决定制作启动图或图标, ...
- 【初级为题,大神绕道】The app icon set named "AppIcon" did not have any applicable content 错误#解决方案#
The app icon set named "AppIcon" did not have any applicable content 错误,怎样解决 按照您的错误提示您应该 ...
- mac app icon 设置
mac app icon 设置 1:目前 mac app 所需要的icon 图标尺寸 icon_16x16.png 16px icon_16x16@2x.png 32px icon_32x32.png ...
- iOS App Icon图标 尺寸规范
Commit to AppStore:1024*1024 //for App IconIcon-60@3x.png:180*180 //iPhone 6 Plus (@3x)Icon-60@2x.pn ...
- The app icon set named "AppIcon" did not have any applicable content.
Develop Tools: xCode 5.1 I write a demo for app settings feature. The tutorial url is here. When I a ...
随机推荐
- Distance function for sqlite
Distance function for sqlite Posted on October 25, 2008 by Dave As part of an iPhone SDK project, I ...
- 迄今为止最硬核的「Java8时间系统」设计原理与使用方法
为了使本篇文章更容易让读者读懂,我特意写了上一篇<任何人都需要知道的「世界时间系统」构成原理,尤其开发人员>的科普文章.本文才是重点,绝对要读,走起! Java平台时间系统的设计方案 几乎 ...
- SpringBoot突报java.lang.NoSuchFieldError分析
SpringBoot项目,引了一个内部的工具包,竟然导致启动失败,报找不到freemarker Configuration类的一个属性,网上的解法都大同小异,最终用了自己的办法解决,花点时间记录下来, ...
- Android开发走过的坑(持续更新)
1 华为 nova真机 打印不出Log 参考资料:http://www.apkbus.com/thread-585228-1-1.html 解决:针对权限问题,我们当然也可以解决的,华为手机在你的拨号 ...
- Google Sign In
我们平常也经常使用QQ,微信账号,登录其他应用.最近公司让我给网站添加一个谷歌账号登录.我来这里记录一下,莫怪~~~莫怪~~~ 1. 申请一个账号登录ID: https://developers.g ...
- C++ 类的继承和派生
继承的优点:减少代码的冗余 提高代码的重用性 派生类定义格式: Class 派生类名 : 继承方式 基类名{ //派生类新增的数据成员和成员函数 }; class 子类: 继承方式 父类名{ //子类 ...
- ASP.NET Core - 在ActionFilter中使用依赖注入
上次ActionFilter引发的一个EF异常,本质上是对Core版本的ActionFilter的知识掌握不够牢固造成的,所以花了点时间仔细阅读了微软的官方文档.发现除了IActionFilter.I ...
- 深入Redis命令的执行过程
深入Redis命令的执行过程 Redis 服务器: Redis 服务器实现与多个客户端的连接,并处理这些客户端发送过来的请求,同时保存客户端执行命令所产生的数据到数据库中.Redis 服务器依靠资源管 ...
- Nginx 轻松学 图文并茂 一学就会 附案例源码
导读 篇幅较长,干货满满,需花费较长时间,转载请注明出处!背景音乐若影响到您,网页选项卡右上角即可关闭~~! Nginx概述 简介 Nginx (engine x) 是一个高性能的HTTP和反向代理w ...
- PyTorch专栏(一)
专栏目录: 第一章:PyTorch之简介与下载 PyTorch简介 PyTorch环境搭建 第二章:PyTorch之60min入门 PyTorch 入门 PyTorch 自动微分 PyTorch 神经 ...