アルファ付きの画像を無理矢理生成するpythonスクリプト

誰が使うんだという感じもするけど、画像から半透明画像を生成するpythonスクリプトを作ったので載せておく。要PIL。

import sys
import PIL.Image

def clamp255(x):
    return max(0, min(255, int(x)))

def get_alpha(b, w):
    alpha = (255 - w[0] + b[0]) / 255.0
    if alpha == 0:
        return (0, 0, 0, 0)
    return (clamp255(round(b[0] / alpha)),
            clamp255(round(b[1] / alpha)),
            clamp255(round(b[2] / alpha)),
            clamp255(round(alpha * 255)))

if len(sys.argv) == 4:
    black = PIL.Image.open(sys.argv[1])
    white = PIL.Image.open(sys.argv[2])

    bw, bh = black.size
    ww, wh = white.size

    if bw == ww and bh == wh:
        output = PIL.Image.new('RGBA', (bw, bh))
        for y in range(bh):
            for x in range(bw):
                c = get_alpha(black.getpixel((x, y)),
                              white.getpixel((x, y)))
                output.putpixel((x, y), c)

        output.save(sys.argv[3])
        exit()

print('Usage: %s black_based_image white_based_image output' % sys.argv[0])
$ python getAlpha.py black.png white.png output.png

↑こんな感じで黒背景と白背景の画像を指定すると画像が生成される。エラー処理は省略。↓は概念図。

例えば、ブラウザの各パーツとかからアルファ付き画像を取り出したい場合に使う。背景の色を操作できないといけないので使える場面は限られるけど。Safari + Macでのフォーカスリングとかこんな感じで取得できる。

<div style="background:#fff;padding:20px;border:1px solid red"><input type="text" style="border:0;background:#fff"></div>
<div style="background:#000;padding:20px;border:1px solid red"><input type="text" style="border:0;background:#000"></div>

こんなHTMLを表示させて適当に大きさをあわせて切り取ると

こんな感じにアルファ付きPNGが出来上がる。

もっといい方法がありそう。