本記事では画像ファイルを繋げて動画にする雛形コードを載せました。下図は、ここ数年でワタクシが呑んで写真を撮った日本酒の一覧で61枚あります。写真の解像度はバラバラであっても、指定したサイズ(本コード中では1920×1080)に調整する仕様のため問題なく動画に出来ます。
下図は、日本酒の情報でexcelファイルにしたものです。動画にする際、上記画像の順番に合わせて、1行毎に情報を画像に付け加える仕様にしています。
作成した動画例は下記リンク先です。音声の付与は、Windows10の標準ソフト「フォト」を使用しています。
■本プログラム
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import os, glob, shutil import pandas as pd import cv2 from PIL import Image, ImageFont, ImageDraw import numpy as np def image_resize(image, height): # 高さに関して指定サイズと現物の比率を計算し、それをx, yに掛けることでアスペクト比を保つ scale = height / image.shape[0] return cv2.resize(image, dsize=None, fx=scale, fy=scale) def image_add_message(img, message): font_path = 'C:\Windows\Fonts\meiryo.ttc' # Windowsのフォントファイルへのパス font_size = 54 # フォントサイズ font = ImageFont.truetype(font_path, font_size) # PILでフォントを定義 img = Image.fromarray(img) # cv2(NumPy)型の画像をPIL型に変換 draw = ImageDraw.Draw(img) # 描画用のDraw関数を用意 # テキストを描画(位置、文章、フォント、文字色(BGR+α)を指定) draw.text((50, 50), message, font=font, fill=(255, 255, 255, 0)) img = np.array(img) # PIL型の画像をcv2(NumPy)型に変換 return img # 文字入りの画像をリターン def jpg2mp4(folder, outfile, width, height, time): img_list = glob.glob(folder + '*.jpg') # ファイルをリストへ格納 print(img_list) fps = len(img_list) / (time*60) # fpsを計算する。ファイル数/再生時間 for i, e in enumerate(img_list): ### ファイル名を連番へリネームする e2 = str(i).zfill(4) + '.jpg' # zfillの型は文字列 #os.rename(e, e2) shutil.copy2(e, e2) # ファイルをカレントディレクトリへコピー img = cv2.imread(e2) ### ファイルサイズを指定サイズへ変更する dst = image_resize(img, height) print(f"{img.shape} -> {dst.shape}") dst_height, dst_width = dst.shape[:2] print("i -> " + str(i) + "/" + str(len(img_list)-1)) print(str(dst_width) + " " + str(dst_height)) ### 無地の画像ファイルをnumpyで作成する new_img = np.zeros((height, width, 3), np.uint8) #cv2.imwrite("blank.bmp", new_img); ### 無地の画像ファイルの上に、元ファイルを上書きする。 ### →全てのファイルが同じ縦横比(アスペクト比)のファイルになる。 if dst_width == width: print("set A") #new_img[上のy座標:下のy座標, 左のx座標:右のx座標] new_img[0:dst_height, 0:dst_width] = dst else: print("set B") offset = int((width - dst_width)/2) print("offset -> " + str(offset)) new_img[0:height, offset:dst_width+offset] = dst ### 挿入するメッセージを加工する my_message_str = '' for j in range(len(my_message_list[i])): if j==0: my_message_str += '紹介No' + str(my_message_list[i][j]) + '\n\n' if j==1: my_message_str += my_message_list[i][j] if j==2: my_message_str += '(' + my_message_list[i][j] + ')' + '\n\n' if j==3: my_message_str += my_message_list[i][j] + '\n\n' if j==4: my_message_str += my_message_list[i][j] + ': ' if j==5: my_message_str += my_message_list[i][j] # メッセージの挿入 new_img = image_add_message(new_img, my_message_str) cv2.imwrite(e2 , new_img) cap = cv2.VideoCapture('%04d.jpg') #fourcc = cv2.VideoWriter_fourcc(*'X264') fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') writer = cv2.VideoWriter(outfile, fourcc, fps, (width, height)) while True: ret, frame = cap.read() if not ret: break writer.write(frame) writer.release() cap.release() print("fps -> " + str(fps)) if __name__ == '__main__': ### 設定項目 input_folder = r"./img/" out_file = 'output.mp4' #'output.avi' out_width = 1920 out_height = 1080 time = 6 #[min] df = pd.read_excel('210626_日本酒一覧.xlsx', sheet_name = 'Sheet1', #index_col = 0, engine = "openpyxl") print(df) my_message_list = df.values.tolist() print(my_message_list) ### 関数呼び出し jpg2mp4(input_folder, out_file, out_width, out_height, time)
ちなみに、本記事で200記事目となりました。
以上
<広告>
リンク
<広告>
リンク