6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

グラデーション画像からAndroidのXMLを自動生成する

Last updated at Posted at 2012-12-06

Androidでは、画像ファイルをそのままアプリにはめこむのではなく、XMLでスタイルを定義することで、画像を作成することができます。

ここで、デザイナが下記のような画像ファイルでボタンを作成したとします。


が、エンジニアは、ここで困ります。XMLでグラデーションを描画するためには、グラデーションの始まりと終わりの色の16進数を入力する必要があるからです。エンジニアがカラーピッカーを立ち上げ、RGBを取得し、16進数に変換する・・・なんて非常に手間がかかります。

というわけで、画像を引数として与えると、XMLを生成してくれるPythonスクリプトを書きました。画像ライブラリとしてPILが必要です。

python generateDrawableXML.py [img_path]

generateDrawableXML.py
    #! /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要素がある画像でも大丈夫。

    <?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="#FFFFC081"  
            android:endColor="#FFFFA349"  
            android:centerColor="#FFFF8101"  
            android:centerY="0.6"  
            />  
    </shape>  

※横方向のグラデーションや、円型のグラデーションには対応していません。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?