複数の画像を連結して動画(mp4、gif)を作成する Python のスクリプトについてまとめ、公開しておきます。
以下の環境で動作確認をしています。
環境: Windows 10 パソコン(+ Anaconda)、Python 3 、OpenCV をインストール済み
※ OpenCV をインストールしていない場合は、設定が必要です。以下の関連リンクを参照してください。
背景
複数の画像を作ったり、写真を撮影したとき、画像をパラパラ漫画のように連結して動画でまとめておきたくなることがあります。
動画編集ソフトを使ってもよいのですが、購入や習得などが煩雑ですし、できるだけ簡単に済ませたいところです。
ということで、フォルダに複数の画像を入れておくと、画像を連結して動画を生成する Python のプログラムをまとめ、公開しておくことにします。
なお、画像処理用に OpenCV、PILを使っています。また、GUI の作成用に Python 標準の tkinter を使っています。
以下のスクリプトでは、連結する元画像のフォーマットは png と jpg 形式としています。また、出力する動画フォーマットは mp4、また、gif としています。
スクリプトで拡張子を書き換えることで、OpenCV が対応している範囲内で、他の画像フォーマットについても対応できると思います。
設定方法
① デスクトップ等にフォルダを作ってください。
② ①のフォルダの中に、”video_generator1.py” の名前でテキストファイルを作り、下記のスクリプトを貼りつけて保存してください。
③ ①のフォルダ内に image1 というフォルダを作成してください。
使い方
④ ③の image1 フォルダに複数の画像(png 画像、又は、jpg 画像など)を入れてください。
画像ファイルは、ファイル名のアルファベット順で連結されます。
必要により、ファイル名には連番を入れるなどして、結合する順番となるようにファイル名をつけてください。
⑤ コンソールから、video_generator (②のスクリプト)を実行してください。
例: Anaconda コンソールで、”python video_generator1.py + [enter] ” 等と入力する。
→ movie 作成用のアプリ video_generator が起動します。
⑥ 「gif 作成」、又は、「mp4 作成」ボタンをクリックしてください。
→ image1 フォルダ内に gif ファイル、又は、mp4 ファイルを出力します。
※ video_generator の GUI 画面上の “image file:” の欄で、デフォルトは “*.png” となっています。
④の画像ファイルの拡張子に応じて、この拡張子の部分を修正してください。jpg 画像であれば、”*.jpg” と
してください。png 画像であれば、変更不要です。
※ 生成される動画ファイル名と画面 frame の表示時間(frame rate の逆数に対応)は、GUI 画面上で設定できるようになっています。必要により修正してください。
スクリプトの説明
ステップ1:フォルダ内の連結用の静止画を取得
GUI は、Python 標準の tkinter を使っています。
まず、スクリプトの冒頭で glob をインポートします。
glob を使って、”image1″ フォルダ内のすべての静止画のファイル名を取得します(png または jpg)。
ステップ2:gif は PIL、mp4 は OpenCV で動画形式を変換
つぎに、GUI 上で設定した出力形式(gif か mp4)に応じて、静止画を結合して出力します。gif は PIL、mp4 は OpenCV の標準機能を使っています。
gif ファイルの生成方法、mp4 ファイルの生成方法の詳細は、関連リンクを参照してください。このソフトウェアは、関連リンクのスクリプトを結合してアプリ化したものです。
まとめ
Python で動画作成をするソフトウェアについてまとめました。これで、複数の画像を連結して動画を生成できるようになりました。
なお、動画に関連する各種ツールや、プログラミングの詳細について、下記の関連リンクにまとめています。もし関心があるようでしたら、参照してみてください。
関連リンク
・ 仮想環境での OpenCV のインストール方法 & エラー時の対処方法 【Anaconda】
・ 画像に文字を書いて出力する 【Python】
・ 複数の画像を連結して mp4 ファイルを生成する方法
・ 動画のダウンロード方法まとめ
・ クリップボードの画像・テキストを自動保存するソフトウェア 【Python】
・ YOLOv5 のインストール手順 【Windows10 & Anaconda】
スクリプト: 動画生成ソフトウェア
#!/usr/bin/env python
# -*- coding: utf8 -*-
import os
import sys
import cv2
import glob
import tkinter
from PIL import Image
def init1():
path1 = os.path.dirname(__file__) + "/image1/"
make_dir1( path1 )
textbox1.delete(0, tkinter.END)
textbox1.insert(0, "*.png")
textbox2.delete(0, tkinter.END)
textbox2.insert(0, "video1")
textbox3.delete(0, tkinter.END)
textbox3.insert(0, "1000")
def make_dir1( path1 ):
if not os.path.isdir( path1 ):
os.makedirs( path1 )
def generate_gif1():
path1 = os.path.dirname(__file__) + "/image1/"
print( path1 )
a1 = glob.glob( path1 + textbox1.get() )
print( a1 )
img1 = list( map( lambda file0: Image.open( file0 ), a1 ) )
file2 = path1 + textbox2.get() + '.gif'
n1 = int( textbox3.get() )
img1[0].save( file2, save_all=True, append_images = img1[1:], duration=n1, loop=0 )
print( "done!" )
def generate_mp4():
path1 = os.path.dirname(__file__) + "\\image1\\"
a1 = glob.glob( path1 + textbox1.get() )
img1 = cv2.imread( a1[0] )
Y1, X1, channels1 = img1.shape[:3]
frame_rate1 = int( 1000.0 / float( textbox3.get() ) )
print( frame_rate1 )
file1 = path1 + textbox2.get() + '.mp4'
fourcc = cv2.VideoWriter_fourcc('m','p','4','v')
video1 = cv2.VideoWriter( file1, fourcc, frame_rate1, (X1, Y1) )
for file0 in a1:
img1 = cv2.imread( file0 )
if img1 is None:
print( "error!" )
else:
img1 = cv2.resize( img1, (X1, Y1) )
video1.write( img1 )
video1.release()
print( "done!" )
root = tkinter.Tk()
root.title(u"video_generator v0.1")
root.geometry("450x80")
label1 = tkinter.Label(text='image file:')
label1.place(x=10, y=5)
label2 = tkinter.Label(text='video file:')
label2.place(x=10, y=35)
label3 = tkinter.Label(text='duration: ms')
label3.place(x=230, y=5)
label4 = tkinter.Label(text='.gif/mp4')
label4.place(x=140, y=35)
textbox1 = tkinter.Entry(master=root)
textbox1.place(x=75, y=5, width=60)
textbox2 = tkinter.Entry(master=root)
textbox2.place(x=75, y=35, width=60)
textbox3 = tkinter.Entry(master=root)
textbox3.place(x=290, y=5, width=60)
btn1 = tkinter.Button(root, text='gif 作成', command=generate_gif1, bg='#c0c0ff' )
btn1.place(x=230, y=35, width=100)
btn2 = tkinter.Button(root, text='mp4 作成', command=generate_mp4, bg='#c0c0ff' )
btn2.place(x=335, y=35, width=100)
init1()
root.mainloop()