チュートリアル、その他のスタックオーバーフローの質問、および PIL ドキュメント自体を見てきましたが、まだその方法がわかりません。
y 軸の約 55% で画像を垂直方向にフェードし始め、約 75% で画像を完全に透明にしたいと思います。最後の 25% 程度は完全に透明にする必要がありますが、画像の高さ全体を保持することが重要です。
これはPILで行うことができますか?
チュートリアル、その他のスタックオーバーフローの質問、および PIL ドキュメント自体を見てきましたが、まだその方法がわかりません。
y 軸の約 55% で画像を垂直方向にフェードし始め、約 75% で画像を完全に透明にしたいと思います。最後の 25% 程度は完全に透明にする必要がありますが、画像の高さ全体を保持することが重要です。
これはPILで行うことができますか?
確かにそれは実行可能です。
透明度のない画像から始めているとしましょう (そうでなければ、質問があいまいになるため)。
ステップ 1: アルファ プレーンを追加します。putalpha
非平面画像を扱っている場合を除き、それは単なるです。その場合、最初に RGB または L に変換する必要があります。
ステップ 2: によって返されたピクセル配列を使用して、変更するピクセルを反復処理しますload
(またはgetpixel
、setpixel
古いバージョンの PIL を処理する必要がある場合)。
ステップ 3: ステップ 3 はありません。画像の保存を考慮しない限り。その場合、OK、ステップ 3 は画像の保存です。
from PIL import Image
im = Image.open('bird.jpg')
im.putalpha(255)
width, height = im.size
pixels = im.load()
for y in range(int(height*.55), int(height*.75)):
alpha = 255-int((y - height*.55)/height/.20 * 255)
for x in range(width):
pixels[x, y] = pixels[x, y][:3] + (alpha,)
for y in range(y, height):
for x in range(width):
pixels[x, y] = pixels[x, y][:3] + (0,)
im.save('birdfade.png')
ここで、アルファは 255 から 0 まで直線的に低下します。別の曲線に従ってドロップオフしたい場合、または RGB8 の代わりに RGB16 を使用している場合、または RGB の代わりに L を使用している場合は、それを変更する方法を理解できるはずです。
これをより速く実行したい場合は、ステップ 2 で Python ループの代わりに numpy を使用できます。または、ステップ 1 と 2 を逆にすることもできます。事前にアルファ プレーンを構築し、それをputalpha
の代わりに に渡すことで、一度にすべて適用できます255
。または…これは私が横たわっていた最大の画像で0.5秒未満だったので、パフォーマンスについてはあまり心配していません.
すでに透明な背景 ( detail ) を持っている画像をフェードしたい場合は、 @abarnertのコードを少し変更する必要があります:
from PIL import Image
im = Image.open('bird.jpg')
width, height = im.size
pixels = im.load()
for y in range(int(height*.55), int(height*.75)):
for x in range(width):
alpha = pixels[x, y][3]-int((y - height*.55)/height/.20 * 255) # change made here
if alpha <= 0:
alpha = 0
pixels[x, y] = pixels[x, y][:3] + (alpha,)
for y in range(y, height):
for x in range(width):
pixels[x, y] = pixels[x, y][:3] + (0,)
bg.save('birdfade.png')