moviepy音视频剪辑:与大小相关的视频变换函数crop、even_size、margin、resize介绍

☞ ░ 前往老猿Python博文目录

一、引言

在《moviepy音视频剪辑:moviepy中的剪辑基类Clip详解》介绍了剪辑基类的fl、fl_time、fx方法,在《moviepy音视频剪辑:视频剪辑基类VideoClip的属性及方法详解》介绍了fl_image和subfx方法,
在《Python+moviepy音视频剪辑:视频帧数据的本质、Clip的fl方法进行变换处理的原理以及滚屏案例》及《moviepy音视频剪辑:使用fl_time进行诸如快播、慢播、倒序播放等时间特效处理的原理和可能遇到的坑》分别介绍了fl和fl_time进行视频剪辑变换的原理及使用方法。

实际上moviepy所有视频变换的方法都是以Clip的fl方法为基础衍生出来的,最后都会调用到fl方法实施真正的变换,只是变换处理的逻辑由上次方法提供,如fl_time就是针对剪辑的时间线进行变换、fl_image就是针对剪辑的内容进行变换,开发者也可以根据自己的需要实现自己的变换方法。

为了支持一些常规的变换处理,moviepy提供了一系列常用的变换函数,开发者可以直接使用这些方法进行变换,这些函数都在moviepy.video.fx包下,基本上一个函数就是一个文件,在moviepy.editor通过import moviepy.video.fx.all as vfx中将这些函数都加载到了vfx模块下,可以直接通过vfx.函数名方式调用,也可以通过VideoClip类+函数名直接调用,这是因为在moviepy.editor执行录入如下语句:

for method in [
    "afx.audio_fadein",
    "afx.audio_fadeout",
    "afx.audio_normalize",
    "afx.volumex",
    "transfx.crossfadein",
    "transfx.crossfadeout",
    "vfx.crop",
    "vfx.fadein",
    "vfx.fadeout",
    "vfx.invert_colors",
    "vfx.loop",
    "vfx.margin",
    "vfx.mask_and",
    "vfx.mask_or",
    "vfx.resize",
    "vfx.rotate",
    "vfx.speedx",
]:

    exec("VideoClip.%s = %s" % (method.split(".")[1], method))

将这些函数动态赋值给了VideoClip的同名实例变量,但这些实例变量是在moviepy.editor中定义的,因此在VideoClip的派生子类中不能这样使用。

这些函数的调用可以通过Clip的fx方法和VideoClip的subfx方法进行调用,具体调用语法请参考上面介绍的博文内容。

由于变换函数比较多,老猿将其以自己的标准分为了大小变换、时间变换、颜色变换、内容变换四个部分分别介绍,这种分法不一定非常对,比如有些部分的变换可能既和时间相关又和内容相关,两个归类都可以,大家就不必深究了。

本文主要介绍和剪辑大小相关的变换函数,包括crop、even_size、margin和resize。

二、crop函数

crop函数从剪辑中获取一个矩形区域的剪辑内容作为新的剪辑。

调用语法:

crop( clip, x1=None, y1=None, x2=None, y2=None, width=None, height=None, x_center=None, y_center=None)

参数:
  1. x1、y1:代表矩形区域左上角坐标
  2. x2、y2:代表矩形区域右下角坐标
  3. width、height:是宽度和高度
  4. x_center、y_center:表示x1的坐标为x_center-width/2,x2的坐标为x_center+width/2,y_center类似处理
数据计算逻辑

下面以横坐标系数据为例来说明矩形位置坐标(单位:像素)的计算逻辑:

  1. 横坐标系数据 x1、x2、width只要出现任意2个就能算出另外1个
  2. x_center如果出现,则可以计算出x1和x2
  3. 如果 x1、x2、width只出现1个或者都未出现,则x1、x2其中未出现的则取原剪辑的左上角或右下角的横坐标,因此单独出现width没有意义
    以上计算过程是有顺序的,只有前面的不满足才会执行后面的。纵坐标系数据同样如此。
案例:
if __name__=='__main__':
    threads = 8

    clipVideo = VideoFileClip(r"F:\video\WinBasedWorkHard_src.mp4").fx(vfx.crop,0,260)
    clipVideo.write_videofile(r"F:\video\crop.mp4", threads=threads)
    clipVideo.close()

原剪辑和执行代码后存储剪辑对应帧图像对比:
在这里插入图片描述
上图中左边为原视频的帧图像,右边为上述代码执行后视频帧的图像。

三、even_size函数

even_size函数是将剪辑的宽和高变成偶数,如果这两个值有为奇数的,则剪辑的帧在丢弃一行或一列像素。这是因为ffmpeg编码规则要求宽和高必须是偶数,相当于一个纠错处理的函数,并没有实际处理的意义。其调用参数就是一个clip。

四、margin函数

margin函数在剪辑的四周增加一个外边框。

调用语法如下:

margin(clip, mar=None, left=0, right=0, top=0, bottom=0, color=(0, 0, 0), opacity = 1.0)

说明:
  • mar:外边框的宽度,以像素为单位,如果mar指定了有效值,则 left、right、top、bottom设定值不起作用
  • left、right、top、bottom:边框左、右、顶和底的宽度
  • color:边框颜色
  • opacity :边框的不透明度,如果为0表示完全透明,1则完全不透明

增加边框的剪辑,其宽度和高度都会相应增加,因此剪辑大小会变大。

案例:
if __name__== '__main__':
    threads = 8
    clip = VideoFileClip(r"F:\video\WinBasedWorkHard_src.mp4").crop(0, 300, 540, 660)

    newclip = clip.fx(vfx.margin, 3, color=(0, 0, 255), opacity=0.5)
    newclip.write_videofile(r"F:\video\WinBasedWorkHard_margin.mp4", threads=threads)
视频效果:

在这里插入图片描述

五、resize函数

resize函数用于调整剪辑的大小,包括缩小或放大。

调用语法:resize(clip, newsize=None, height=None, width=None, apply_to_mask=True)
说明:
  • 使用resize必须先安装了OpenCV、Scipy或PIL图像处理模块中的一个,否则不能使用
  • newsize可以是返回新剪辑的宽和高二元组,也可以是大小变化的比例如0.5或2,还可以是一个和剪辑帧时间t相关的函数来返回前面2种值中的一个
  • width、height:剪辑的宽或高,二者指定一个,另一个会自动计算

六、小结

本文主要介绍和剪辑大小相关的变换函数,包括crop、even_size、margin和resize,相关的函数会在原剪辑大小的基础上进行大小变化,包括裁取其中一部分、给剪辑增加边框和调整剪辑大小等,返回新剪辑。

更多moviepy的介绍请参考《PyQt+moviepy音视频剪辑实战文章目录》或《专栏:使用PyQt开发图形界面Python应用》。

广告

老猿关于PyQt的付费专栏《使用PyQt开发图形界面Python应用》只需要9.9元(老猿正在考虑是否调整专栏价格,如果调整价格至少是19.9元),本专栏《PyQt+moviepy音视频剪辑实战》文档的同样内容在付费专栏上也有相应内容,总体来说付费专栏介绍更详细或案例更多。

本节内容对应付费专栏的《moviepy音视频剪辑:与大小相关的视频变换函数详解》。如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python、学5G!

☞ ░ 前往老猿Python博文目录

猜你喜欢

转载自blog.csdn.net/LaoYuanPython/article/details/107238651