Как мне наложить прозрачную векторную анимацию гизе на видеоролик? - PullRequest
0 голосов
/ 08 января 2019

Я не могу понять, как наложить анимацию гизе на видео, чтобы векторная графика была видимой, а фон прозрачным, чтобы видео было видно под анимацией. Я пробовал много разных способов и ничего не получается. Все, что я когда-либо получаю, это анимация гизех, полностью скрывающая основное видео.

Это была моя последняя попытка, я просто пытался нарисовать красную линию поверх видео, я пытался использовать метод mask_color vfx, чтобы создать маску, которая использует Surface bg_color, но это не имеет никакого эффекта .

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))

Как определить и применить маску анимированного графического клипа?

1 Ответ

0 голосов
/ 09 января 2019

Зулько, автор moviepy и gizeh очень любезно помог мне найти решение этой проблемы (полная информация здесь https://github.com/Zulko/moviepy/issues/898).

Хитрость в том, чтобы:

  • Используйте одну и ту же функцию make_frame для графики и анимации.
  • Возвращает массив пустых изображений с параметром transparent=True, который возвращает значение непрозрачности для каждого пикселя после значений RGB [поэтому форма массива (ширина, высота, 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)

...