Pythonでいろいろやってみる

Pythonを使った画像処理や機械学習などの簡単なプログラムを載せています。

フォルダ内の画像からスライドショーを作る(フェード切り替え)

 指定したフォルダ内の画像を読み出しスライドショーを作ります。画像はサイズがまちまちなのでスライドショーのサイズに対して横幅が大きい場合は左右を、高さが大きい場合は上下をカットして、スライドショーのサイズに自動で変換します。画像と画像の切り替えは前の画像が少しずつ薄れ次の画像が少しずつ濃くなるように(いわゆるフェードもしくはディゾルブ)前後の画像をアルファブレンドしアルファ値を変化させています。
 画像処理ライブラリPillowのcropで画像のサイズ合わせを、blendで前後の画像のアルファブレンドを行っています。   

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 5.6.0
  • Python 3.8.8
  • Pillow 8.2.0
準備

 以下の画像ファイルをフリー写真素材ぱくたそからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにフォルダ'photos'を作成しその中に保存しました。
f:id:T_A_T:20220124191718j:plain
asama.jpg

f:id:T_A_T:20220124191740j:plain
autumn.jpg

f:id:T_A_T:20220124191819j:plain
cat.jpg

f:id:T_A_T:20220124191906j:plain
girl.jpg

f:id:T_A_T:20220124191925j:plain
hongkong.jpg

f:id:T_A_T:20220124191937j:plain
xmas.jpg

コード

 photosフォルダに含まれるファイルのリストを作り、画像を読み出してサイズを調整しtempフォルダに格納します。tempフォルダから画像を読み出し20コマgifファイルに追加、続く20コマで前後の画像をアルファブレンドし徐々に次の画像に移るように見せます。最後の画像から最初の画像へのディゾルブが必要なのでファイルのリストの最後に一番最初の画像をもう一度追加しています。

import os
from PIL import Image

# 画像フォルダのパス
dir_path = 'photos/' 
# フォルダ内のファイルをリストに
files = os.listdir(dir_path)
# 1番目のファイルをリストの最後に追加
files.append(files[0]) 

# スライドショーの幅、高設定
s_width, s_height = 500, 250
# スライドショーのアスペクト比(高さ/幅)
s_aspect = s_height/s_width

# gifファイル作成用イメージリスト
images =[] 

# サイズ調整した画像の一時保存用リスト
temp = []

# 画像をサイズ調整しリストに追加
for i in range(len(files)):
    # 画像の読み出し
    im = Image.open(dir_path + files[i])
    # 画像幅、高さの取得、アスペクト比(高さ/幅)の算出
    width = im.width
    height = im.height
    aspect = height/width
    # 画像のアスペクト比がスライドショーと同じ場合そのままスライドショーサイズにリサイズ
    if aspect == s_aspect:
        resize = im.resize((s_width, s_height))            
    # 画像のアスペクト比がスライドショーより大きい場合上下をカットしスライドショーサイズにリサイズ
    if aspect > s_aspect:
        crop_size = int((height-s_aspect*width)/2)
        crop = im.crop((0, crop_size, width, height-crop_size))
        resize = crop.resize((s_width, s_height))    
    # 画像のアスペクト比がスライドショーより小さい場合左右をカットしスライドショーサイズにリサイズ
    if aspect < s_aspect:
        crop_size = int((width-height/s_aspect)/2)
        crop = im.crop((crop_size, 0, width-crop_size, height))
        resize = crop.resize((s_width, s_height))
    # リサイズした画像をリストに追加    
    temp.append(resize)

# リストから画像を読みだしスライドショーに
for i in range(len(files)-1):
    # 画像の読み出し
    im = temp[i]
    # 次の画像の読み出し
    im2 = temp[i+1]  
    # gifファイルに画像を20コマ追加    
    for j in range(20):
        images.append(im)      
    # 次の画像とブレンドして画像をゆっくり切り替える    
    for j in range(20):
        blend = Image.blend(im, im2, j/19)
        images.append(blend)
        
# gif動画保存
images[0].save('slideshow.gif', save_all=True, append_images=images[1:], 
               optimize=False, duration=50, loop=0)  

実行結果

スライドショーがgifアニメーションになって保存されます。画像は徐々に切り替わります(フェードもしくはディゾルブ)。
f:id:T_A_T:20220124183504g:plain

以下のサイトを参考にさせていただきました

note.nkmk.me>>Python, OpenCV, Pillow(PIL)で画像サイズ(幅、高さ)を取得
Pythonの文法メモ > 【Pillow】画像のアルファブレンド(blend、alpha_composit)
Pythonの文法メモ > 【Pillow】画像の縮小拡大(resize)、切り抜き(crop)

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村