File size: 2,340 Bytes
dd74184
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
from moviepy.editor import ImageClip, ColorClip, concatenate_videoclips, CompositeVideoClip
import os
import re
import natsort
from PIL import Image
import numpy as np
from concurrent.futures import ThreadPoolExecutor

def process_image(file, duration, target_size):
    with Image.open(file) as img:
        width, height = img.size
        ratio = width / height
        new_width, new_height = target_size

        if width > target_size[0] or height > target_size[1]:
            if ratio > target_size[0] / target_size[1]:
                new_width = target_size[0]
                new_height = int(new_width / ratio)
            else:
                new_height = target_size[1]
                new_width = int(new_height * ratio)

        resized_img = img.resize((new_width, new_height), resample=Image.Resampling.LANCZOS)
        img_clip = ImageClip(np.array(resized_img)).set_duration(duration).set_position('center')
        return img_clip

def images_to_video_with_durations(input_image_path, output_video_path, durations, fps, base_name):
    # 获取所有符合条件的图片,并按文件名中的数字排序
    pattern = re.compile(rf'^{re.escape(base_name)}_(\d+)\.png$')
    image_files = [
        os.path.join(input_image_path, file)
        for file in os.listdir(input_image_path)
        if pattern.match(file)
    ]
    image_files = natsort.natsorted(image_files, key=lambda x: int(pattern.match(os.path.basename(x)).group(1)))

    # 确定视频的背景尺寸
    target_size = (1280, 720)

    # 创建背景剪辑
    bg_clip = ColorClip(size=target_size, color=(255, 255, 255), duration=sum(durations))

    # 使用多线程处理图像文件
    with ThreadPoolExecutor() as executor:
        clips = list(executor.map(process_image, image_files, durations, [target_size] * len(image_files)))

    # 将所有剪辑叠加到背景上
    composite_clips = [CompositeVideoClip([bg_clip.subclip(sum(durations[:i]), sum(durations[:i+1])), clip]) 
                       for i, clip in enumerate(clips)]

    # 使用concatenate_videoclips函数将所有剪辑串联起来
    final_clip = concatenate_videoclips(composite_clips, method="compose")

    # 写入视频文件
    output_filename = f"{base_name}.mp4"
    final_clip.write_videofile(os.path.join(output_video_path, output_filename), fps=fps)