U8SDK——自动处理渠道SDK的角标(补充)
参照之前@徒步同学分享的一篇统一自动处理各个渠道的角标,我也试着在U8SDK中实现这种方式。本文就分享一下,我的实现思路和中间遇到的一些问题。
我们知道,很多渠道SDK是要求在游戏的图标上,加上渠道SDK提供的角标。以前我们通常的做法是,让美术人员去完成游戏图标和角标合在一起的工作。这样不仅费时费力,而且效率低下。之前U8SDK中的处理是,将这些事先已经合上角标的图标放在各个渠道配置目录下的res目录下,名称必须和游戏中的图标名称一样。这样打包工具在合并资源的时候,会把渠道SDK配置目录下的资源覆盖到母包反编译后的目录,这样打出来的渠道包,就自然是新的含有角标的图标了~
但是,这个方式效率依然是低下的,因为还是需要美术同学去将游戏图标和角标合在一起,然后发给游戏客户端同学。那么,之前@徒步同学提供了很棒的思路,这里我们就按照他提供的方式,使用python中的Pillow图片处理模块来自动实现将渠道SDK的角标合在游戏图标上。
关于Pillow模块的安装,可以参照@徒步之前的文章,这里不再赘述。补充一点,如果你按照之前我说的,将u8sdk打包工具升级到了python3.x,那么你就无需再像 “#ff0000;”>之前的文章 “#3366ff;”>上说的那样去下载PIL模块安装了,直接在命令行中运行 pip install Pillow 即可完成Pillow模块的安装
实现思路:
1、在打包工具的各个游戏配置目录下,加一个子目录icon。在这个子目录中,放一个512 * 512的游戏图标的ICON。注意,一定要是PNG格式。
2、在各个渠道SDK配置目录下,加一个子目录icon_marks。在这个目录下放置该渠道SDK要求的角标。注意,角标大小为512*512的PNG。角标的名称必须是
left-bottom.png,left-top.png,mini-icon.png,right-bottom.png,right-top.png 分别对应着:左下角角标,左上角角标,中下角小角标,右下角角标,右上角角标。
3、在渠道配置文件的channel节点中,我们增加一个 value的值分别为lb,lt,mb,rb,rt分别对应:left-bottom.png,left-top.png,mini-icon.png,right-bottom.png,right-top.png五种类型的角标
4、在打包脚本中,我们通过channel[‘icon’]这个参数来判定当前要使用哪个角标。然后将游戏配置目录下的icon.png和当前指定的角标.png使用图像处理工具合并在一起,形成一个512*512的含有角标的图标。
5、获取当前游戏AndroidManifest.xml的application节点中配置的图标名称,比如叫@drawable/app_icon。
6、将刚刚合成好的含有角标的图标,进行缩放,并输出到反编译目录/res目录下,对应各个分辨率的目录下。分别是drawable-ldpi(3636),drawable-mdpi(4848),drawable-hdpi(7272),drawable-xhdpi(9696),drawable-xxhdpi(144*144)五个目录下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
def getAppIconName(decompileDir): """ 从AndroidManifest.xml中获取游戏图标的名称 """ manifestFile = decompileDir + "/AndroidManifest.xml" manifestFile = file_utils.getFullPath(manifestFile) ET.register_namespace('android', androidNS) tree = ET.parse(manifestFile) root = tree.getroot() applicationNode = root.find('application') if not applicationNode: return "ic_launcher" key = '{'+androidNS+'}icon' iconName = applicationNode.get(key) if not iconName: return "ic_launcher" name = iconName[10:] file_utils.printF("The game icon name is now "+name) return name def appendChannelIconMark(game, channel, decompileDir): """ 自动给游戏图标加上渠道SDK的角标 """ gameIconPath = 'config/games/' + game['appName'] + '/icon/icon.png' gameIconPath = file_utils.getFullPath(gameIconPath) if not os.path.exists(gameIconPath): file_utils.printF("The game %s icon path is not exists:%s", game['appName'], gameIconPath) return 1 if 'icon' not in channel: file_utils.printF("The channel %s of game %s not config icon in config.xml", channel['name'], game['appName']) return 1 markType = channel['icon'] markName = 'right-bottom' if markType == 'rb': markName = 'right-bottom' elif markType == 'rt': markName = 'right-top' elif markType == 'lt': markName = 'left-top' elif markType == 'lb': markName = 'left-bottom' elif markType == 'mb': markName = 'mini-icon' markPath = 'config/sdk/' + channel['name'] + '/icon_marks/' + markName + '.png' if not os.path.exists(markPath): file_utils.printF("The icon mark %s is not exists of channel %s ", markPath, channel['name']) return 1 gameIcon = Image.open(gameIconPath) markIcon = Image.open(markPath) rlImg = image_utils.appendIconMark(gameIcon, markIcon, (0, 0)) rlImg.show() ldpiSize = (36, 36) mdpiSize = (48, 48) hdpiSize = (72, 72) xhdpiSize = (96, 96) xxhdpiSize = (144,144) ldpiIcon = rlImg.resize(ldpiSize, Image.ANTIALIAS) mdpiIcon = rlImg.resize(mdpiSize, Image.ANTIALIAS) hdpiIcon = rlImg.resize(hdpiSize, Image.ANTIALIAS) xhdpiIcon = rlImg.resize(xhdpiSize, Image.ANTIALIAS) xxhdpiIcon = rlImg.resize(xxhdpiSize, Image.ANTIALIAS) ldpiPath = file_utils.getFullPath(decompileDir + '/res/drawable-ldpi') mdpiPath = file_utils.getFullPath(decompileDir + '/res/drawable-mdpi') hdpiPath = file_utils.getFullPath(decompileDir + '/res/drawable-hdpi') xhdpiPath = file_utils.getFullPath(decompileDir + '/res/drawable-xhdpi') xxhdpiPath = file_utils.getFullPath(decompileDir + '/res/drawable-xxhdpi') if not os.path.exists(ldpiPath): os.makedirs(ldpiPath) if not os.path.exists(mdpiPath): os.makedirs(mdpiPath) if not os.path.exists(hdpiPath): os.makedirs(hdpiPath) if not os.path.exists(xhdpiPath): os.makedirs(xhdpiPath) if not os.path.exists(xxhdpiPath): os.makedirs(xxhdpiPath) gameIconName = getAppIconName(decompileDir) + '.png' file_utils.printF("The game icon name is "+gameIconName) ldpiIcon.save(os.path.join(ldpiPath, gameIconName), 'PNG' ,quality = 95) mdpiIcon.save(os.path.join(mdpiPath, gameIconName), 'PNG' ,quality = 95) hdpiIcon.save(os.path.join(hdpiPath, gameIconName), 'PNG' ,quality = 95) xhdpiIcon.save(os.path.join(xhdpiPath, gameIconName), 'PNG' ,quality = 95) xxhdpiIcon.save(os.path.join(xxhdpiPath, gameIconName), 'PNG' ,quality = 95) return 0 def appendIconMark(imgIcon, imgMark, position): """ 将两张同样大小的图片叠加在一起 """ if imgIcon.mode != 'RGBA': imgIcon = imgIcon.convert('RGBA') markLayer = Image.new('RGBA', imgIcon.size, (0,0,0,0)) markLayer.paste(imgMark, position) return Image.composite(markLayer, imgIcon, markLayer) |
本文出自 U8SDK技术博客,转载时请注明出处及相应链接。
本文永久链接: http://www.uustory.com/?p=1778