1. 问题描述和解答
2. 代码实现
import math
import random
import uuid
from moviepy.editor import *
def center_image(file_name, width, height, scale, pos_x, pos_y):
w = (width - pos_x * width * 2) / scale
h = (height - pos_y * height * 2) / scale
x = pos_x * width / (2 * scale)
y = pos_y * height / (2 * scale)
x = math.ceil(x) + random.randint(10, 20) # 放置计算误差导致x、y偏小
y = math.ceil(y) + random.randint(10, 20)
new_w = 6 * x + 3 * w
new_h = 6 * y + 3 * h
crop_w = int(new_w / 2 - width / 2)
crop_h = int(new_h / 2 - height / 2)
clip1 = ImageClip(file_name)
clip_w, clip_h = clip1.size
ratio = clip_w / w
clip1 = clip1.fx(vfx.resize, newsize=(w, h))
clip1 = clip1.fx(vfx.margin, left=x, right=x,
top=y, bottom=y,
color=(255, 255, 255), opacity=0.0)
clip2 = clip1.fx(vfx.mirror_x)
clip3 = clip1.fx(vfx.mirror_y)
clip31 = clip3.fx(vfx.mirror_x)
final_clip = clips_array([[clip31, clip3, clip31],
[clip2, clip1, clip2],
[clip31, clip3, clip31]])
print(final_clip.size)
final_clip = final_clip.fx(vfx.crop, x1=crop_w, y1=crop_h, width=width, height=height)
save_file = str(uuid.uuid4()) + '.png'
final_clip.save_frame(save_file, withmask=True)
return final_clip, ratio
if __name__ == '__main__':
def size(t, total_duration, start_scale, end_scale):
if start_scale == end_scale:
return end_scale
if t < total_duration:
relative_time = t / total_duration
scale = start_scale + relative_time * (end_scale - start_scale)
else:
scale = end_scale
return scale
in_scale = 0.75
pos_x, pos_y = (1 - in_scale) / 2, (1 - in_scale) / 2
scale = 2.0
width = 1080
height = 1440
s = '/Users/admin/an.jpg'
final_clip, ratio = center_image(s, width, height, scale, pos_x, pos_y)
final_clip = final_clip.to_ImageClip()
duration = 3
ic = ImageClip("/Users/admin/2.jpg",
duration=duration)
ic = ic.resize((width, height))
final_clip = final_clip.set_duration(duration)
final_clip = final_clip.resize(lambda t: size(t, duration, 1.0, scale))
final_clip = final_clip.set_position(('center', 'center'))
cvc = CompositeVideoClip([ic, final_clip])
cvc.write_videofile("r1.mp4", fps=24)
3. 结果和素材
liu