ここで、デザイナが下記のような画像ファイルでボタンを作成したとします。
が、エンジニアは、ここで困ります。XMLでグラデーションを描画するためには、グラデーションの始まりと終わりの色の16進数を入力する必要があるからです。エンジニアがカラーピッカーを立ち上げ、RGBを取得し、16進数に変換する・・・なんて非常に手間がかかります。
というわけで、画像を引数として与えると、XMLを生成してくれるPythonスクリプトを書きました。画像ライブラリとしてPILが必要です。
GitHub
python generateDrawableXML.py [img_path]
#! /usr/bin/env python # -*- coding: utf-8 -*- import sys from PIL import Image def getCenterList(_list, order=1): if order > 0: return [i for (i, x) in enumerate(_list) if x == max(_list)] else: return [i for (i, x) in enumerate(_list) if x == min(_list)] def getHexColor(rgb): return '#FF' + getHexStr(rgb[0]) + getHexStr(rgb[1]) + getHexStr(rgb[2]) def getHexStr(color): hexStr = hex(color)[2:].upper() return hexStr if len(hexStr) == 2 else '0' + hexStr def main(path): img = Image.open(path) img = img.resize((1, img.size[1])) img = img.convert("RGB") rgbs = list(img.getdata()) height = len(rgbs) startRGB = rgbs[0] endRGB = rgbs[len(rgbs) - 1] centerRGB = None centerIndex = 0 rs, gs, bs = [], [], [] for rgb in rgbs: rs.append(rgb[0]) gs.append(rgb[1]) bs.append(rgb[2]) for i in [-1, 1]: centerSet = set(getCenterList(rs, i)) & set(getCenterList(gs, i)) & set(getCenterList(bs, i)) if len(centerSet) == 0: continue index = list(centerSet)[0] if index != 0 and index != (height - 1): centerRGB = rgbs[index] centerIndex = index centerStr = "" if centerRGB: centerStr = """ android:centerColor="%s" android:centerY="%s" """ % (getHexColor(centerRGB), round(float(centerIndex) / float(height - 1), 1)) print """ <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:angle="270" android:type="linear" android:startColor="%s" android:endColor="%s"%s /> </shape>""" % (getHexColor(startRGB), getHexColor(endRGB), centerStr) if __name__ == '__main__': argvs = sys.argv if len(argvs) != 2: print("python " + argvs[0] + " [img_path]") else: main(argvs[1])
実行すると下記XMLが生成されます。
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:angle="270" android:type="linear" android:startColor="#FF330F55" android:endColor="#FFC45D19" /> </shape>
また、center要素がある画像でも大丈夫。
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:angle="270" android:type="linear" android:startColor="#FFFFC081" android:endColor="#FFFFA349" android:centerColor="#FFFF8101" android:centerY="0.6" /> </shape>
※横方向のグラデーションや、円型のグラデーションには対応していません。