動画作成ソフトウェア【Python】

Python

複数の画像をフォルダに入れておくと連結して動画(mp4、gif)を作成する Python プログラムです。OpenCV で動画作成をしています。

以下の環境で動作確認をしています。
環境: Windows 10、Python 3 (+ Anaconda 3)、OpenCV をインストール済み

背景

複数の画像を生成したり、写真を撮影したとき、画像をパラパラ漫画のように連結して動画でまとめておきたくなることがあります。ネットにあるソフトウェアをダウンロードすることも考えられますが、セキュリティ上不安があります。
そこで、Python で画像を連結するソフトウェアをユーザーインターフェースつきで作成しましたので公開します。カスタマイズも自由となり、安心です。
なお、画像処理用に OpenCV、PIL、GUI の作成用に Python 標準の tkinter を使っています。
スクリプトに記載したとおり、元の画像フォーマットは png と jpg 形式について、出力する動画フォーマットは mp4、また、gif について行っています。
拡張子を書き換える程度で多くの画像フォーマットについても対応できると思います。

設定方法

① デスクトップ等にフォルダを作ってください。
② ①のフォルダの中に、”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 で動画作成をするソフトウェアについてまとめました。これで、複数の画像を連結して動画を生成できるようになりました。

なお、動画に関連する各種ツールや、プログラミングの詳細について、下記の関連リンクにまとめています。もし関心があるようでしたら、参照してみてください。

関連リンク
・ 画像に文字を書いて出力する 【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()

 

タイトルとURLをコピーしました