如何将gizeh矢量动画叠加到具有透明度的moviepy视频上?

问题描述 投票:0回答:1

我无法弄清楚如何将gizeh动画叠加到视频上,以便矢量图形可见,但背景是透明的,因此视频在动画下方可见。我已经尝试了很多不同的方法,似乎没有任何工作。我所得到的只是完全隐藏底层视频的gizeh动画。

这是我最近的努力,只是简单地尝试在视频上绘制一条红线,我尝试使用mask_color vfx方法创建一个使用Surface bg_c​​olor的蒙版,但它没有任何效果。

import gizeh
from moviepy.editor import *

def make_frame(t):
    surface = gizeh.Surface(width=720, height=1280, bg_color=(0.5, 0.5, 0))
    line = gizeh.polyline(points=[(0, 1180), (720, 1180)], stroke_width=3, stroke=(1, 0, 0))
    line.draw(surface)
    return surface.get_npimage()


original_clip = VideoFileClip("test_original_video.mp4")
graphics_clip = VideoClip(make_frame, duration=original_clip.duration)
masked_graphics_clip = vfx.mask_color(graphics_clip, [0.5, 0.5, 0])

final_clip = CompositeVideoClip(
    [original_clip,
     graphics_clip],
    size=(720, 1280))

final_clip.write_videofile("test_output_video.mp4", fps=30))

如何定义和应用动画图形剪辑的蒙版?

python vector-graphics moviepy
1个回答
0
投票

moviepy和gizeh的作者Zulko非常友好地帮助我找到了解决方案(详情请参阅https://github.com/Zulko/moviepy/issues/898)。

诀窍是:

  • 对图形和动画使用相同的make_frame函数。
  • 使用transparent=True选项返回numpy图像数组,该选项返回RGB值后每个像素的不透明度值[所以数组的形状为(width,height,4)]
  • 对于蒙版剪辑,对数组进行切片,使其仅使用不透明度值[给出(宽度,高度,1)的形状]
  • 对于图形剪辑,对数组进行切片,使其仅使用RGB值[给出(宽度,高度,3)的形状]
  • 将蒙版剪辑应用于图形剪辑

工作代码如下所示:


    import gizeh
    from moviepy.editor import *

    def make_frame(t):
        surface = gizeh.Surface(width=720, height=1280)
        line = gizeh.polyline(points=[(0, 1180), (720, 1180)], stroke_width=10, stroke=(1, 0, 0))
        line.draw(surface)
        return surface.get_npimage(transparent=True)


    original_clip = VideoFileClip("test_original_video.mp4")

    graphics_clip_mask = VideoClip(lambda t: make_frame(t)[:, :, 3] / 255.0, 
                                   duration=original_clip.duration, ismask=True)
    graphics_clip = VideoClip(lambda t: make_frame(t)[:, :, :3],
                              duration=original_clip.duration).set_mask(graphics_clip_mask)

    final_clip = CompositeVideoClip(
        [original_clip,
         graphics_clip],
        size=(720, 1280)
    )

    final_clip.write_videofile("test_output_video.mp4", fps=30)

© www.soinside.com 2019 - 2024. All rights reserved.