Skip to content

Instantly share code, notes, and snippets.

@oshinko
Last active April 2, 2022 13:12
Show Gist options
  • Save oshinko/7d7d9b508f5d6137d112e34fe62f2d99 to your computer and use it in GitHub Desktop.
Save oshinko/7d7d9b508f5d6137d112e34fe62f2d99 to your computer and use it in GitHub Desktop.
Convert images to mp4
import pathlib
import subprocess
try:
import cv2
except ModuleNotFoundError:
import sys
subprocess.run(f'{sys.executable} -m pip install opencv-python',
shell=True)
import cv2
finally:
import numpy as np
# とりあえず固定
VIDEO_FILE = 'video.mp4'
VIDEO_WIDTH = 1280
VIDEO_HEIGHT = 720
VIDEO_DURATION = 20
VIDEO_FPS = 20
def iterimgs():
path = pathlib.Path.cwd() # 引数で渡しても良いかも
for x in sorted(path.iterdir()):
if x.suffix in ['.jpg', '.png']:
if x.is_absolute():
# 日本語が含まれるパスだと cv2.imread に失敗するので、
# なるべく回避できるように相対パスに変換している。
x = x.relative_to(pathlib.Path.cwd())
yield cv2.imread(str(x))
vf = pathlib.Path(VIDEO_FILE) # 引数で渡しても良いかも
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
n_imgs = len(list(iterimgs()))
n_dups = int(VIDEO_DURATION * VIDEO_FPS / n_imgs)
def iterfrms():
for img in iterimgs():
for _ in range(n_dups):
yield img
# iterimgs で全画像の大きさを取ってから設定しても良いかも
vw, vh = VIDEO_WIDTH, VIDEO_HEIGHT
video = cv2.VideoWriter(str(vf), fourcc, VIDEO_FPS, (vw, vh))
if not video.isOpened():
print(f"can't open {vf}")
exit()
for img in iterfrms():
# 動画サイズに合わせて画像をリサイズ
h, w = img.shape[:2]
scale = min(vw / w, vh / h)
img = cv2.resize(img, (int(w * scale), int(h * scale)))
h, w = img.shape[:2]
# キャンバス (最終的にフレームとなる)
cvs = cv2.resize(np.zeros((1, 1, 3), np.uint8), (vw, vh))
# 貼り付け
wpad = int((vw - w) / 2)
wpad_lmt = w + wpad
hpad = int((vh - h) / 2)
hpad_lmt = h + hpad
cvs[hpad:hpad_lmt, wpad:wpad_lmt] = img
# 書き込み
video.write(cvs)
video.release()
# ffmpeg があれば H.264 に変換
try:
tmp = pathlib.Path('tmp').with_suffix(vf.suffix)
subprocess.run(f'ffmpeg -i {vf} -vcodec libx264 {tmp}', shell=True)
except FileNotFoundError:
pass
else:
print('converted to H.264 using ffmpeg')
vf.write_bytes(tmp.read_bytes())
tmp.unlink()
print('written')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment