""" Утилиты для создания видео из последовательности изображений """ import cv2 import numpy as np from pathlib import Path from typing import List from utils.image_processor import ImageProcessor class VideoCreator: """Создатель видео из серии изображений""" @staticmethod def create_timelapse(image_paths: List[Path], output_path: Path, fps: int = 10) -> Path: """ Создает видео из последовательности изображений Args: image_paths: Список путей к изображениям output_path: Путь для сохранения видео fps: Кадров в секунду Returns: Путь к созданному видео """ if not image_paths: raise ValueError("Нет изображений для создания видео") # Загружаем первое изображение для определения размера first_img = ImageProcessor.load_jp2(str(image_paths[0])) if first_img is None: raise ValueError("Не удалось загрузить первое изображение") height, width = first_img.shape[:2] # Определяем кодек и создаем VideoWriter output_str = str(output_path) fourcc = cv2.VideoWriter_fourcc(*'mp4v') video_writer = cv2.VideoWriter(output_str, fourcc, fps, (width, height)) # Добавляем все изображения for img_path in image_paths: # Загружаем изображение img_data = ImageProcessor.load_jp2(str(img_path)) if img_data is not None: # Конвертируем RGB в BGR для OpenCV img_bgr = cv2.cvtColor(img_data, cv2.COLOR_RGB2BGR) video_writer.write(img_bgr) video_writer.release() return output_path @staticmethod def create_gif(image_paths: List[Path], output_path: Path, duration: int = 200) -> Path: """ Создает GIF анимацию из изображений Args: image_paths: Список путей к изображениям output_path: Путь для сохранения GIF duration: Длительность кадра в миллисекундах Returns: Путь к созданному GIF """ from PIL import Image images = [] for img_path in image_paths: img_data = ImageProcessor.load_jp2(str(img_path)) if img_data is not None: pil_image = Image.fromarray(img_data) images.append(pil_image) if images: # Сохраняем GIF images[0].save( output_path, save_all=True, append_images=images[1:], duration=duration, loop=0 ) return output_path