如何通过Drawtext给视频画上文字,并且能够给文字旋转个角度,比如30度角?本文将重点介绍一下利用FFmpeg如何做到这样的效果,首先看一下效果图:
这样的效果操作原理比较简单,步骤如下:
1. 给文字创建一个需要写字的画布,带上纯色
2. 因为旋转的话,可能会有对角被画出原本宽高范围导致显示不全,所以可以计算一下文字宽高,需要显示的文字的个数,旋转角度后需要用的显示宽高,然后计算出来在画布的显示偏移,这样就可以了
3. 将文字铺在画布上之前做一个旋转,旋转后剩余的空间填充与画布纯色相同的颜色
4. 将旋转后的文字铺在画布上
5. 用纯色抠图的colorkey设置Alpha通道
6. 将抠图设置好Alpha通道后的图像数据铺在最终需要铺的画布的位置
整个过程看上去相对来说比较简单。
用到的滤镜主要如下:
- lavfi 可以作为输入设备的滤镜例如color,testsrc,testsrc2等
- drawtext 用来绘制文字,主要需要使用FreeType、Fontconfig
- rotate 用来旋转角度用,但是这里面参数是弧度,需要自己演算一下角度
- colorkey 用来做纯色抠像,主要根据传入的颜色设置一下 Alpha
- overlay 和名字一样的功能
其实主要需要注意的参数是drawtext与rotate部分的,看一下参数说明:
Filter drawtext
Draw text on top of video frames using libfreetype library.
Inputs:
#0: default (video)
Outputs:
#0: default (video)
drawtext AVOptions:
fontfile <string> ..FV..... set font file
text <string> ..FV..... set text
textfile <string> ..FV..... set text file
fontcolor <color> ..FV..... set foreground color (default "black")
fontcolor_expr <string> ..FV..... set foreground color expression (default "")
boxcolor <color> ..FV..... set box color (default "white")
bordercolor <color> ..FV..... set border color (default "black")
shadowcolor <color> ..FV..... set shadow color (default "black")
box <boolean> ..FV..... set box (default false)
boxborderw <int> ..FV..... set box border width (from INT_MIN to INT_MAX) (default 0)
line_spacing <int> ..FV..... set line spacing in pixels (from INT_MIN to INT_MAX) (default 0)
fontsize <string> ..FV..... set font size
x <string> ..FV..... set x expression (default "0")
y <string> ..FV..... set y expression (default "0")
shadowx <int> ..FV..... set shadow x offset (from INT_MIN to INT_MAX) (default 0)
shadowy <int> ..FV..... set shadow y offset (from INT_MIN to INT_MAX) (default 0)
borderw <int> ..FV..... set border width (from INT_MIN to INT_MAX) (default 0)
tabsize <int> ..FV..... set tab size (from 0 to INT_MAX) (default 4)
basetime <int64> ..FV..... set base time (from I64_MIN to I64_MAX) (default I64_MIN)
font <string> ..FV..... Font name (default "Sans")
expansion <int> ..FV..... set the expansion mode (from 0 to 2) (default normal)
none ..FV..... set no expansion
normal ..FV..... set normal expansion
strftime ..FV..... set strftime expansion (deprecated)
timecode <string> ..FV..... set initial timecode
tc24hmax <boolean> ..FV..... set 24 hours max (timecode only) (default false)
timecode_rate <rational> ..FV..... set rate (timecode only) (from 0 to INT_MAX) (default 0/1)
r <rational> ..FV..... set rate (timecode only) (from 0 to INT_MAX) (default 0/1)
rate <rational> ..FV..... set rate (timecode only) (from 0 to INT_MAX) (default 0/1)
reload <boolean> ..FV..... reload text file for each frame (default false)
alpha <string> ..FV..... apply alpha while rendering (default "1")
fix_bounds <boolean> ..FV..... check and fix text coords to avoid clipping (default false)
start_number <int> ..FV..... start frame number for n/frame_num variable (from 0 to INT_MAX) (default 0)
ft_load_flags <flags> ..FV..... set font loading flags for libfreetype (default 0)
default ..FV.....
no_scale ..FV.....
no_hinting ..FV.....
render ..FV.....
no_bitmap ..FV.....
vertical_layout ..FV.....
force_autohint ..FV.....
crop_bitmap ..FV.....
pedantic ..FV.....
ignore_global_advance_width ..FV.....
no_recurse ..FV.....
ignore_transform ..FV.....
monochrome ..FV.....
linear_design ..FV.....
no_autohint ..FV.....
This filter has support for timeline through the 'enable' option.
最好一行不差的读完,不会英语的用有道翻译,谷歌翻译都可以,不知道某讯有没有翻译产品,反正我没用过,估计是翻译产品应该都差不多可以知道啥意思。
本文主要用了这么几个参数:
- fontfile 用来指定字体文件,比如微软雅黑比较常见,就是系统里面的ttc、ttf、otf这类字体
- x 文字显示的x坐标
- y 文字显示的y坐标
- fontsize 文字大小
文字部分大概介绍完毕。下面看一下rotate参数。
rotate的参数如下:
Filter rotate
Rotate the input image.
slice threading supported
Inputs:
#0: default (video)
Outputs:
#0: default (video)
rotate AVOptions:
angle <string> ..FV..... set angle (in radians) (default "0")
a <string> ..FV..... set angle (in radians) (default "0")
out_w <string> ..FV..... set output width expression (default "iw")
ow <string> ..FV..... set output width expression (default "iw")
out_h <string> ..FV..... set output height expression (default "ih")
oh <string> ..FV..... set output height expression (default "ih")
fillcolor <string> ..FV..... set background fill color (default "black")
c <string> ..FV..... set background fill color (default "black")
bilinear <boolean> ..FV..... use bilinear interpolation (default true)
This filter has support for timeline through the 'enable' option.
本问主要用到了如下两个参数:
- angle或者a 注意看说明,这可不是角度,是弧度,弧度与角度有个计算公式,需要自己去平面几何基础课程补一下相关知识。
- fillcolor或者c 旋转后原来显示图像的区域需要填充些什么,比如黑色,白色等,默认是黑色。
命令行部分:
好,基本部分描述完毕,下面我们看一下怎么拼一下这样的命令行:
ffmpeg -i ~/Movies/objectC/facebook.mp4 -filter_complex "color=White:s=400x400[v1];[v1]drawtext=fontfile=/Library/Fonts/Songti.ttc:text='这是什么东西?':x=60:y=50:fontsize=20[o1];[o1]rotate=a=-PI*30/180:fillcolor=White@0[o1];[o1]colorkey=White:0.01:1[o2];[0:v][o2]overlay=x=(W-w)/2:y=(H-h)/2" -y b.mp4
这条命令行执行后,效果图就是本文第一张图的效果。
API部分:
命令行部分介绍完了,下面是上API使用时间,看一下API部分怎么操作。
StevenLiu:dash StevenLiu$ git diff
diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c
index e48837cbd2..5dbcd376e8 100644
--- a/doc/examples/transcoding.c
+++ b/doc/examples/transcoding.c
@@ -391,7 +391,7 @@ static int init_filters(void)
if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
- filter_spec = "null"; /* passthrough (dummy) filter for video */
+ filter_spec = "color=White:s=400x400[v1];[v1]drawtext=fontfile=/Library/Fonts/Songti.ttc:text='这是什么东西?':x=60:y=50:fontsize=20[o1];[o1]rotate=a=-PI*30/180:fillcolor=White@0[o1];[o1]colorkey=White:0.01:1[o2];[in][o2]overlay=x=(W-w)/2:y=(H-h)/2"; /* passthrough (dummy) filter for video */
else
filter_spec = "anull"; /* passthrough (dummy) filter for audio */
ret = init_filter(&filter_ctx[i], stream_ctx[i].dec_ctx,
照着做问题不大。这回就介绍这么些。
作者:悟空;公众号:流媒体技术
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。