实现思路 🤔
- 基于ffmpeg,画布的方式,创建画布 -> 水印 -> 旋转 -> 抠图 -> 叠加到图像上
- 基于ffmpeg,旋转图片的方式,填充 -> 水印 -> 顺时针旋转 -> 逆时针旋转 -> 截图
- 基于opencv,创建画布 -> 水印 -> 仿射变换 -> 水平垂直拼接 -> 叠加图片上
经测试比对,opencv实现方式效率是最快的
代码实现 💨
- FFmpeg
-
旋转画布方式
- 这种方式相对实现简单一些,但经过试验,对于一个2k的视频,实现全屏文字倾斜,效率太慢了 。不知道是我代码问题,还是什么问题。如果有大佬能提高效率,方便指导一二,抱拳了.
- 实现参考
-
旋转图片方式
- 思路:
- 首先将图片填充放大,然后计算出水印位置,叠加水印,再逆时针将图片旋转回来,字体就变斜了。然后通过剪裁,将图片剪切成原图大小。
- 基于
ffmpeg filter
实现
// 填充 // [in]scale=原图宽:原图高,pad=填充后宽:填充后高:填充左右大小:填充上下大小:black[out] // 四周填充, pad 输入尺寸的一半 char dtext[512]; snprintf(dtext, sizeof(dtext), "[in]scale=%d:%d,pad=%d:%d:%d:%d:black[out]", frameWidth, frameHeight, expandFrameWidth, expandFrameHeight, expandSize, expandSize); // 水印 // inxxxx[a];[a]xxx[a];[a]xxx[out] 中间传的文字标签首位对应([a] [a]). 结束没有';'. char dtext[1000]; snprintf(dtext, sizeof(dtext), "[in]drawtext=fontfile=%s:text=%s:x=%d:y=%d:fontsize=%d:fontcolor=%s:alpha=%.1f[a];",kFont, txt.c_str(), start_x, start_y, kFontSize, kFontColor, italicTextInfo_.alpha); // 翻转 // [in]rotate=PI* angel /180[out] char dtext[512]; snprintf(dtext, sizeof(dtext), "[in]rotate=PI* %d /180[out]", angel); // 截取 // [in]crop=原图宽:原图高:截取x:截取y[out] char dtext[512]; snprintf(dtext, sizeof(dtext), "[in]crop=%d:%d:%d:%d[out]", frameWidth, frameHeight, startx, starty);
- 创建
AVFilterGraph
int init_filter_graph(const std::string& filter) { filterGraph_ = avfilter_graph_alloc(); const AVFilter* buffersrc = avfilter_get_by_name("buffer"); const AVFilter* buffersink = avfilter_get_by_name("buffersink"); char args[512]; snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", frameWidth_, frameHeight_, frameFormat_, 1, videoFps_, 1, 1); int ret = avfilter_graph_create_filter(&buffersrcCtx_, buffersrc, "in", args, NULL, filterGraph_); if (ret < 0) { avfilter_graph_free(&filterGraph_); filterGraph_ = NULL; return -1; } // buffer video sink: to terminate the filter chain. enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FM
- 思路:
-