Pythonで複数枚のPNG画像から動画をつくる方法

これはなに Link to this heading

この記事では、Pythonのopencvというライブラリを用いて、複数の画像ファイルを結合し、パラパラ漫画のような動画ファイルに変換する方法を紹介する。

画像から動画を作成する手順 Link to this heading

最初に、必要なライブラリであるopencvglobをインストールする。

pip install opencv-python
pip install opencv-python-headless
pip install glob2

次に、以下のPythonスクリプトを使って、画像を動画ファイルに変換する。このPythonスクリプトは、指定されたディレクトリ内の画像ファイルを読み込み、順番に動画へ追加する。

import cv2
import os
import glob


def create_video_from_image_folder(
    image_folder: str,
    output_file: str,
    image_extension: str = "png",
    frame_rate: int = 24,
) -> None:
    """
    Create a video file from a sequence of image files in the specified folder.

    Parameters
    ----------
    image_folder : str
        The path to the folder containing the image files.
    output_file : str
        The filename of the video file to be created.
    image_extension : str, optional, default="png"
        The file extension of the image files (default is "png").
    frame_rate : int, optional, default=24
        The desired frame rate of the output video (default is 24).

    Raises
    ------
    ValueError
        If no image files are found in the specified folder.
    """

    # Get a list of image file paths in the specified folder, sorted in ascending order
    image_filepaths = sorted(
        glob.glob(os.path.join(image_folder, f"*.{image_extension}"))
    )

    if not image_filepaths:
        raise ValueError("No image files found.")

    # Read the first image to get its dimensions (height and width)
    first_image = cv2.imread(image_filepaths[0])
    height, width, _ = first_image.shape

    # Initialize the video writer with the specified output file,
    # codec, frame rate, and dimensions
    video_writer = cv2.VideoWriter(
        output_file,
        cv2.VideoWriter_fourcc(*"mp4v"),
        frame_rate,
        (width, height),
    )

    # Iterate over the image file paths, read each image, and write it to the video
    for image_filepath in image_filepaths:
        current_image = cv2.imread(image_filepath)
        video_writer.write(current_image)

    # Release the video writer and close the output file
    video_writer.release()
    print(f"Video file created: {output_file}")


# Set the required variables for creating the video
image_folder_path = "/path/to/your/image/folder"
output_video_name = "output_video.mp4"
image_file_extension = "png"
video_frame_rate = 24

# Call the function with the specified variables to create the video
create_video_from_image_folder(
    image_folder_path, output_video_name, image_file_extension, video_frame_rate
)

このスクリプトを実行すると、指定したディレクトリ内のPNG画像を順番に読み込み、出力動画ファイルに追加する。動画のフレームレートはデフォルトで24fpsに設定しているが、異なるフレームレートも使用できる。

動画にテキストを追加する方法 Link to this heading

動画作成時に、各画像に異なるテキストを追加できる。

import cv2
import os
import glob


def overlay_text_on_image(
    image: cv2.Mat,
    text: str,
    position: tuple[int, int],
    font=cv2.FONT_HERSHEY_SIMPLEX,
    font_scale: float = 1,
    color: tuple[int, int, int] = (255, 255, 255),
    thickness: int = 2,
) -> cv2.Mat:
    """
    Overlay the given text on an image at the specified position.

    Parameters
    ----------
    image : cv2.Mat
        The image to overlay text on.
    text : str
        The text to overlay.
    position : tuple[int, int]
        The x and y coordinates of the text position.
    font : int, optional
        Font type, by default cv2.FONT_HERSHEY_SIMPLEX.
    font_scale : float, optional
        Font scale, by default 1.
    color : tuple[int, int, int], optional
        Text color in BGR format, by default (255, 255, 255).
    thickness : int, optional
        Text thickness, by default 2.

    Returns
    -------
    cv2.Mat
        The image with the text overlay.
    """
    img_with_text = image.copy()
    cv2.putText(img_with_text, text, position, font, font_scale, color, thickness)
    return img_with_text


def create_video_from_images(
    img_folder: str,
    output_path: str,
    img_format: str = "png",
    fps: int = 24,
    titles: list[str] | None = None,
) -> None:
    """
    Create a video from images in the specified folder.

    Parameters
    ----------
    img_folder : str
        The folder containing the images.
    output_path : str
        The path to save the output video file.
    img_format : str, optional
        The image file format, by default "png".
    fps : int, optional
        The frames per second for the output video, by default 24.
    titles : list[str] | None, optional
        A list of titles for each image, by default None.

    Raises
    ------
    ValueError
        If no image files are found
        or if the number of titles does not match the number of images.
    """
    # Get image files in the specified folder and sort by filename
    img_files = sorted(glob.glob(os.path.join(img_folder, f"*.{img_format}")))

    if not img_files:
        raise ValueError("No image files found.")

    if titles is not None and len(titles) != len(img_files):
        raise ValueError("Number of titles does not match the number of image files.")

    frame = cv2.imread(img_files[0])
    height, width, _ = frame.shape

    video = cv2.VideoWriter(
        output_path,
        cv2.VideoWriter_fourcc(*"mp4v"),  # Specify the video file codec
        fps,
        (width, height),
    )

    for index, img_file in enumerate(img_files):
        frame = cv2.imread(img_file)

        if titles is not None:
            text = titles[index]
            frame = overlay_text_on_image(
                frame, text, (10, 30), font_scale=1, color=(40, 40, 40), thickness=2
            )

        video.write(frame)

    video.release()
    print(f"Video created: {output_path}")


img_folder = "/path/to/your/image/folder"  # Path to the image folder
output_path = "output_video.mp4"  # Name of the output video file
img_format = "png"  # Image file format
fps = 24  # Frame rate
titles = [
    "Title 1",
    "Title 2",
    "Title 3",
]  # List of titles for each image. Set to None to skip adding text.

create_video_from_images(img_folder, output_path, img_format, fps, titles)

テキストの色を変更したい場合は、colorの値を変更する。

Licensed under CC BY-NC-SA 4.0
最終更新 5月 21, 2023
Hugo で構築されています。
テーマ StackJimmy によって設計されています。