PILで透過GIFをRGBAに

PILでGIF画像を開くと、モードは「P」。つまりパレットモード。透過GIFの場合、パレット内のどのカラーが透明かは分かるけど、透過GIFのImageオブジェクトをさくっとRGBAモードに変換するメソッドがPILには用意されていない。

この変換のやり方がようやく分かった。これでいろいろと合成ができる。
半年近く前にもトライして諦めたんだけど、なんでこんなコードが書けなかったのか不思議なくらい単純な方法でできた。
でも検索しても全然出てこないから、みんな分からないのだと思う。というか、そんなニーズがないのかも知れない。

コードは次の通り。

def convert_trasparent_gif_to_rgba(img):
    rgb_img = img.convert('RGB')
    transparent_color_index = img.info['transparency']
    alphadata = [0 if p == transparent_color_index else 255 for p in img.getdata()]
    alpha_img = Image.new('L', img.size, 0)
    alpha_img.putdata(alphadata)

    rgb_img.putalpha(alpha_img)
    return rgb_img

    #上2行の代わりに以下2行でもOK
    #imgs = rgb_img.split()
    #return Image.merge('RGBA', (imgs[0], imgs[1], imgs[2], alpha_img))

img = Image.open('image_with_transparency.gif')
rgba_img = convert_transparent_gif_to_rgba(img)

alphadataを得る部分が、画像サイズが大きくなるとかなり非効率。まあ、透過GIFでそんな巨大な画像は作らないしね。
でももっとオシャレな方法がありそうな気はしてる。

Last updated on July 7, 2015