简体   繁体   English

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

[英]How do I overlay a gizeh vector animation onto a moviepy video with transparency?

I can't work out how to overlay a gizeh animation onto a video so that the vector graphics are visible but the background is transparent so the video is visible underneath the animation.我无法弄清楚如何将 gizeh 动画叠加到视频上,以便矢量图形可见但背景是透明的,因此视频在动画下方可见。 I've tried lots of different ways and nothing seems to work.我尝试了很多不同的方法,但似乎没有任何效果。 All I ever get is the gizeh animation completely hiding the underlying video.我得到的只是完全隐藏底层视频的 gizeh 动画。

This was my latest effort, just simply trying to draw a red line over the video, I've tried using the mask_color vfx method to create a mask that uses the Surface bg_color, but it doesn't have any effect.这是我最近的努力,只是试图在视频上画一条红线,我尝试使用mask_color方法创建一个使用 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))

How do I define and apply the mask of the animated graphics clip?如何定义和应用动画图形剪辑的蒙版?

Zulko, the author of moviepy and gizeh very kindly helped me find a solution to this (full details here https://github.com/Zulko/moviepy/issues/898 ). moviepy 和 gizeh 的作者 Zulko 非常好心地帮助我找到了解决方案(完整的细节在这里https://github.com/Zulko/moviepy/issues/898 )。

The trick is to:诀窍是:

  • Use the same make_frame function for both the graphics and the animation.对图形和动画使用相同的make_frame函数。
  • Return the numpy image array with the transparent=True option, which returns an opacity value for each pixel after the RGB values [so the shape of the array is (width, height, 4)]使用transparent=True选项返回 numpy 图像数组,它返回 RGB 值之后每个像素的不透明度值 [因此数组的形状是 (width, height, 4)]
  • For the mask clip, slice the array so it only uses the opacity value [giving a shape of (width, height, 1)]对于蒙版剪辑,对数组进行切片,使其仅使用不透明度值 [给出形状为 (width, height, 1)]
  • For the graphics clip, slice the array so it only use the RGB values [giving a shape of (width, height, 3)]对于图形剪辑,对数组进行切片,使其仅使用 RGB 值 [给出形状为 (width, height, 3)]
  • Apply the mask clip to the graphics clip将蒙版剪辑应用到图形剪辑

The working code looks like this:工作代码如下所示:


    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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM