张老师问我有没有什么好的办法批量生成视频。帮他参考了一下,发现他只有生成答案那里不能自动化。

他的答案是这样的形式呈现:

很明显,下面5个答案不能做到批量生成,只能一个一个手打上去。一开始我也没有很好的办法,因为我的答案也是五线谱的形式,相对来说没有这么简洁精致。

仔细想了想,分解开来其实就是黑色的方块上加上白色的字。不知道python上关于绘图的库能不能做到这一点

pillow

这是python上的一个图像库,中文文档地址是点击此处
我需要用到的就是三个模块,分别是:Image,ImageDraw,ImageFont

首先生成一个纯黑色的底版。

from PIL import Image, ImageDraw, ImageFont
# 生成一个背景
background=Image.new("RGB", (100, 100), (0,0,0))
background.show()

Image.new()里面需要传入三个参数,具体如下:

  • mode:有"RGB"、"RGBA"等模式。具体可以去参考文档。
  • size:输入一个元组用来表示宽与高的像素。
  • color:输入rgb的数值确定颜色。

show()函数是可以预览生成的图像。效果如下:

接下来就是要把字母打上去。

from PIL import Image, ImageDraw, ImageFont
# 生成一个背景
background=Image.new("RGB", (100, 100), (0,0,0))
# 在背景上生成文字
draw=ImageDraw.Draw(background)
draw.text((50,50), "bE",anchor="mm",fill=(255,255,255))
background.show() 

因为是要在背景上面添加文字,所有首先要使用ImageDraw.Draw()函数,并传入代表背景的实例background

接下来使用text()函数添加文字。此函数能传入的参数非常多,我选择传入部分。

  • xy:这代表文本的锚点坐标。在上例中我选择了(50,50),因为背景是(100, 100)所以正好是最中心的位置。
  • text:需要添加的文字。如果输入多行文字可能用到multiline_text()函数更加合适,具体参考文档。
  • anchor:文本锚点对齐方式。简单的可以理解文本的中心点在哪里,默认情况下会是左上角。我输入的文本是bE,那么将会从坐标(50,50)即中心点开始绘制文本,显然字是不会在中心的。所以我传入参数anchor="mm",让文本居中对齐。具体参考文档。
  • fill:文本的颜色。用rgb数值来进行控制。

效果如下:

字虽然是在中间,但是有点太小了。我们还需要对字体大小进行调整。

from PIL import Image, ImageDraw, ImageFont

# 设定字体文件与大小
ttf=ImageFont.truetype("/Users/xhhdd/Desktop/Alibaba-PuHuiTi-Medium.ttf", 60)
# 生成一个背景
background=Image.new("RGB", (100, 100), (0,0,0))
# 在背景上生成文字
draw=ImageDraw.Draw(background)
draw.text((50,50), "bE",anchor="mm",fill=(255,255,255),font=ttf)
background.show()

这里使用了ImageFont.truetype()函数,并传入了部分参数进行控制。

  • font:输入字体文件的路径,对字体文件进行加载。
  • size:字体大小,以磅为单位。

接下来在text()函数中添加了font=ttf的参数,确保使用这个字体。效果如下:

那么这个基本上就跟张老师要的效果相差无几了。最后就是使用save()函数保存即可。如:background.save('black.png')

生成背景图

平时在批量制作视频时,视频封面总是一个麻烦问题。
我一般出一系列就是20个视频,在cdr中制作好一个封面模板之后,再去修改左上角的数字角标。如下:

还有一个比较重要的问题,就是不同平台的分辨率是不太一样的。像b站的封面就略宽一点,小红书就稍微窄一点。

现在有了pillow之后,我应该可以写一个这样的工具,只需要输入内容就可以自动生成对应平台的封面。

首先是b站的封面,封面比例是16:9,需要大于1146 717。我稍微做大一点,定为3438 2151。接下来定一下左上角角标的位置,跟正文的位置。

# -*- coding: utf-8 -*-
from PIL import Image,ImageDraw,ImageFont

def cover():
    # 设定字体文件与大小
    body_ttf=ImageFont.truetype("/Users/xhhdd/Desktop/Alibaba-PuHuiTi-Medium.ttf",350)
    make_ttf=ImageFont.truetype("/Users/xhhdd/Desktop/Alibaba-PuHuiTi-Medium.ttf",150)
    # 生成一个背景
    background=Image.new("RGB",background_size,background_color) 
    # 确定角标位置
    footnote=ImageDraw.Draw(background)
    fn_x,fn_y=int(background_size[0]*(1/5)),int(background_size[1]*(1/7))
    footnote.text((fn_x,fn_y),footnote_text,anchor="mm",fill=footnote_color,font=make_ttf)
    # 确定正文位置
    body=ImageDraw.Draw(background)
    bd_x,bd_y=int(background_size[0]*(1/2)),int(background_size[1]*(2/5))
    body.multiline_text((bd_x,bd_y),body_text,anchor="mm",fill=body_color,font=body_ttf,spacing=space)
    background.show()
    background.save('cover.png')

# ---------------------------------------
# 调整下列数值即可运行
# 背景颜色|用rgb数值控制
background_color=(252,77,83)
# 背景大小|默认是b站的比例3438,2151
background_size=(3438,2151)

# 角标的文字
footnote_text='「1」'
# 角标的颜色|用rgb数值控制
footnote_color=(255,255,255)

# 正文内容
body_text='听\n单 音' # \n代表换行符
# 正文文字颜色|用rgb数值控制∂
body_color=(255,255,255)

# 两行文字之间的间距
space=200

cover()

效果如下:
cover
除了下面那行字,效果基本上差不多了~
加个循环就可以批量生成封面了!

最后修改:2022 年 06 月 19 日
如果觉得我的文章对你有用,请随意赞赏