89 lines
No EOL
3.1 KiB
Python
89 lines
No EOL
3.1 KiB
Python
"""
|
||
Утилиты для создания видео из последовательности изображений
|
||
"""
|
||
|
||
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 |