0
0

Pillowを使って画像ファイルからフェードエフェクトを適用したスライドショー動画を作成する

Posted at

概要

複数の画像ファイルからスライドショーの動画を作成するのは ffmpeg 等で簡単に可能ですが、単に画像を結合した場合では以下のようにやや味気ないスライドショーになってしまいます。

フェードなしスライドショー

そこで、以下のようなフェードエフェクトを導入することで、ややリッチな動画になります。

フェードありスライドショー

ffmpeg でもフェードの導入は可能ですが、入力ファイルの数が多いとコマンドが煩雑になるため、ここでは Python で実装する方法を紹介します。

入力画像

入力する画像は何でも良いですが、ここでは例として CC0 ライセンスで利用可能な Pixabay の画像を利用します。

以下の5枚をダウンロードし、./img/ に保存します。

Pythonによる実装

Pythonを使ってフェードエフェクトを導入した動画を作成します。Pillow の Image.blend で連続する2枚の画像をブレンドしたフレームを生成し、 OpenCV の cv2.VideoWriter を用いて動画を出力するという内容になっています。

import pathlib

import cv2
import numpy as np
from PIL import Image


def main():
    fps = 10  # 出力する動画のフレームレート
    fade_frames = 20  # 入力画像1枚に対するフェード適用後のフレーム数

    img_dir = pathlib.Path("./img/")
    imgs = [Image.open(img_file) for img_file in img_dir.glob("*.jpg")]

    deltas = np.linspace(0.0, 1.0, fade_frames, endpoint=False)  # フェード適用時のフレーム割り

    fourcc = cv2.VideoWriter_fourcc(*"H264")
    video = cv2.VideoWriter("video.mp4", fourcc, fps, imgs[0].size)

    for i in range(len(imgs) - 1):
        for delta in deltas:
            alpha = (1 - np.cos(delta * np.pi)) / 2  # 三角関数で滑らかに補間する
            img_blended = Image.blend(imgs[i], imgs[i + 1], alpha)  # delta=0(alpha=0)では元画像が使われる
            video.write(cv2.cvtColor(np.asarray(img_blended), cv2.COLOR_RGB2BGR))
    video.write(cv2.cvtColor(np.asarray(imgs[-1]), cv2.COLOR_RGB2BGR))  # 最後の元画像のフレームも追加

    video.release()


if __name__ == "__main__":
    main()

実行すると、 video.mp4 に以下の動画が出力されます。(記事上では別途出力したgif動画を貼り付けています。)

フェードありスライドショー

Image.blend の引数 alpha の算出方法の違いによる差異

上記実装の22行目では alpha = (1 - np.cos(delta * np.pi)) / 2 として、三角関数を使った補間をしていますが、Image.blend の引数 alpha は0~1の数値であれば良いので、 alpha = delta としても問題はありません。以下は alpha = delta とした場合と alpha = (1 - np.cos(delta * np.pi)) / 2 とした場合の比較です。

alphaによる差異の比較

alpha = delta
alpha = (1 - np.cos(delta * np.pi)) / 2

好みのレベルですが、三角関数で補間した右の方がややメリハリが効いた遷移に見えます。

0
0
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
0
0