【音视频】使用movie、drawtext过滤器实现图片、文字水印(6-3)

news2024/9/21 0:40:33

本来准备从六月份开始研究使用ffmpeg的movie filter实现图片水印、drawtext filter实现文字水印的能力,但一直没时间,临近中秋终于有空,于是研究了下ffmpeg命令行(这里不做展示,关注代码实现),从中转化为C++代码实现。

直接上代码,这里新增了视频水印类,以下是主要实现:

int VideoWaterMarker::init(const VIDEO_FILTER_CTX& outCtx, const VIDEO_FILTER_CTX* inCtx0, const VIDEO_FILTER_CTX* inCtx1)
{
	int err = ERROR_CODE_OK;

	if (m_inited) {
		return err;
	}

	if (inCtx0 == nullptr) {
		err = ERROR_CODE_PARAMS_ERROR;
		return err;
	}

	do {
		m_filterGraph = avfilter_graph_alloc();
		if (m_filterGraph == nullptr) {
			err = ERROR_CODE_FILTER_ALLOC_GRAPH_FAILED;
			break;
		}

		m_filterInCtxs = new VIDEO_FILTER_CTX;
		memcpy_s(&m_filterInCtxs[0], sizeof(VIDEO_FILTER_CTX), inCtx0, sizeof(VIDEO_FILTER_CTX));
		m_filterOutCtx = outCtx;

		m_filterInCtxs[0].filterInout = avfilter_inout_alloc();
		m_filterOutCtx.filterInout = avfilter_inout_alloc();

		char filterInArg[512] = { 0 };
		sprintf_s(filterInArg, sizeof(filterInArg), "video_size=%dx%d:pix_fmt=%d:frame_rate=%d:time_base=%d/%d:pixel_aspect=%d/%d",
			m_filterInCtxs[0].width, m_filterInCtxs[0].height, m_filterInCtxs[0].pixelFmt, m_filterInCtxs[0].framerate,
			m_filterInCtxs[0].timebase.num, m_filterInCtxs[0].timebase.den, m_filterInCtxs[0].pixelAspect.num, m_filterInCtxs[0].pixelAspect.den);

		int ret = avfilter_graph_create_filter(&m_filterInCtxs[0].filterCtx, avfilter_get_by_name("buffer"), "in", filterInArg, nullptr, m_filterGraph);
		if (ret < 0) {
			err = ERROR_CODE_FILTER_CREATE_FILTER_FAILED;
			break;
		}

		ret = avfilter_graph_create_filter(&m_filterOutCtx.filterCtx, avfilter_get_by_name("buffersink"), "out", nullptr, nullptr, m_filterGraph);
		if (ret < 0) {
			err = ERROR_CODE_FILTER_CREATE_FILTER_FAILED;
			break;
		}

		av_opt_set_bin(m_filterOutCtx.filterCtx, "pix_fmts", (uint8_t*)&m_filterOutCtx.pixelFmt, sizeof(m_filterOutCtx.pixelFmt), AV_OPT_SEARCH_CHILDREN);

		m_filterInCtxs[0].filterInout->name = av_strdup("in");
		m_filterInCtxs[0].filterInout->filter_ctx = m_filterInCtxs[0].filterCtx;
		m_filterInCtxs[0].filterInout->pad_idx = 0;
		m_filterInCtxs[0].filterInout->next = nullptr;

		m_filterOutCtx.filterInout->name = av_strdup("out");
		m_filterOutCtx.filterInout->filter_ctx = m_filterOutCtx.filterCtx;
		m_filterOutCtx.filterInout->pad_idx = 0;
		m_filterOutCtx.filterInout->next = nullptr;

		std::string filterDesc;
		/* 1、图片水印 */
		filterDesc = "movie=11.png[wm];[in][wm]overlay=W-w:H-h[out]";
		/* 2、文字水印 */
		std::wstring tempText = L"Hello, 世界!";
		std::string strText = HELPER::StringConverter::convertUnicodeToUtf8(tempText);
		filterDesc = "drawtext=fontfile=\'C\\:/Windows/Fonts/simsun.ttc\':fontsize=72:fontcolor=white:box=1:boxcolor=blue@0.5:x=w-text_w:y=h-text_h:text=\'" + strText + "\'";
		/* 3、时间水印 */
		filterDesc = "drawtext=fontfile=\'C\\:/Windows/Fonts/Arial.ttf\':text=\'%{localtime\\:%Y-%m-%d %H.%M.%S}\':fontsize=36:fontcolor=white:box=1:boxcolor=blue:x=100:y=50";
		ret = avfilter_graph_parse_ptr(m_filterGraph, filterDesc.c_str(), &m_filterOutCtx.filterInout, &m_filterInCtxs[0].filterInout, nullptr);
		if (ret < 0) {
			err = ERROR_CODE_FILTER_PARSE_PTR_FAILED;
			break;
		}

		ret = avfilter_graph_config(m_filterGraph, nullptr);
		if (ret < 0) {
			err = ERROR_CODE_FILTER_CONFIG_FAILED;
			break;
		}

		m_inited = true;
	} while (0);

	if (err != ERROR_CODE_OK) {
		LOGGER::Logger::log(LOGGER::LOG_TYPE_ERROR, "[%s] init mixer, error: %s", __FUNCTION__, HCMDR_GET_ERROR_DESC(err));
		cleanup();
	}

	return err;
}

1、对于图片的水印,使用movie filter将图片作为一个输入源[wm]跟另外一个视频输入源[in](摄像头或桌面采集)输出新的[out]视频源。“movie=11.png[wm];[in][wm]overlay=W-w:H-h[out]”,其中W、H是[in]的大小,w、h是[wm]的大小,将[wm]overlay在[in]上面,且显示在右下角。
2、对于文字水印,使用drawtext filter,首先要指定绝对路径的文字文件,例如fontfile=‘C\:/Windows/Fonts/simsun.ttc’,在windows下一定要这样写,要不然找不到指定的文字文件而使用默认的文字文件,其次文字输入如果包含中文则需要将其转化为UTF8格式作为text的值传入。一般文字大小从8磅到72磅,这里指定文字大小为72磅,颜色为白色,box=1表示开启文字背景色,指定背景色为蓝色且透明度为50%(文字也可以像这样单独指定透明度;如果要同时指定文字和背景色透明度,可以使用命令alpha=0.5),这里x、y将文字位置至于右下角。
3、对于时间水印,同样需要指定绝对路径fontfile,其次text需要指定例如text=‘%{localtime\:%Y-%m-%d %H.%M.%S}’,Y表示年,m表示月份,d表示天,H表示小时,M表示分钟,S表示秒,Arial字体的时间样式:
在这里插入图片描述

PS:因为视频水印也是线程驱动的,剩下的一些实现如开始线程start()、停止线程stop()、喂帧addFrame()、清空cleanup()和线程函数mixProcess()跟《【音视频】视频混流-avfilter(2-2)》类似,可以跳转参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2128173.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI客服机器人开启企业客户服务新纪元

随着人工智能(AI)技术的迅猛发展&#xff0c;使得AI客服机器人走进了我们的视野&#xff0c;成为提高客户满意度和业务效率的不二法宝。这些智能机器人不仅能够处理海量信息&#xff0c;还能为客户提供个性化的服务体验。 一、AI客服机器人的基本原理 AI客服机器人是基于人工智…

Azure web app has no access to openai private endpoint in virtual network

题意&#xff1a;"Azure Web 应用无法访问虚拟网络中的 OpenAI 私有端点。" 问题背景&#xff1a; I am trying to host a web application similar to a private ChatGPT instance within a secluded virtual network, ensuring that theres no external internet …

​年化收益52%,最大回撤13%,卡玛比率3.77,ETF轮动系列大有可为(附策略代码和数据下载)。

原创内容第648篇&#xff0c;专注量化投资、个人成长与财富自由。 今天继续开发策略&#xff0c;先看结果&#xff1a; 年化52%&#xff0c;最大回撤13%&#xff0c;卡玛比率3.77。 策略逻辑&#xff1a; 买入规则&#xff1a; 5日均线大于20日均线 。 最近20个交易日的涨…

【Prompt Engineering:思维树 (ToT)、检索增强生成 (RAG)、自动推理并使用工具 (ART)】

思维树 (ToT) 对于需要探索或预判战略的复杂任务来说&#xff0c;传统或简单的提示技巧是不够的。最近&#xff0c;Yao et el. (2023)(opens in a new tab) 提出了思维树&#xff08;Tree of Thoughts&#xff0c;ToT&#xff09;框架&#xff0c;该框架基于思维链提示进行了总…

全球著名地标卫星影像收藏第5辑

世界那么大&#xff0c;一起去看看&#xff01; 我们在《全球著名地标卫星影像收藏第4辑》一文中&#xff0c;为大家分享了10全球著名地标高清卫星影像&#xff0c;现在继续为大家分享10个著名地标。 我们整理这些地标的KML文件分享大家&#xff0c;也可以打开相应URL链接即可…

tofixed和math.round什么区别

1、floor 返回不大于的最大整数&#xff08;向下取整&#xff09; 2、round 则是4舍5入的计算&#xff0c;入的时候是到大于它的整数&#xff08;当-1.5时可见&#xff0c;四舍五入后得到的结果不是我们期待的&#xff0c;解决办法是先对他取绝对值&#xff0c;然后在用round方…

全平台7合一自定义DIY小程序源码系统 数据库结构全新升级 带完整的安装代码包以及搭建部署教程

系统概述 随着小程序市场的日益成熟&#xff0c;越来越多的企业和个人开始意识到小程序在品牌推广、用户获取和服务提供方面的巨大潜力。然而&#xff0c;传统的小程序开发方式往往存在开发周期长、成本高、灵活性差等问题&#xff0c;难以满足快速变化的市场需求。因此&#…

如何做尘埃粒子计数器校准,多久一次?北京中邦兴业

尘埃粒子计数器的校准是确保其测量准确性和可靠性的重要环节。以下是关于尘埃粒子计数器校准的详细说明&#xff1a; 一、校准目的 尘埃粒子计数器作为评估和监控洁净室及其他控制环境中空气质量的关键仪器&#xff0c;其准确性和可靠性直接关系到数据的准确性和有效性。定期校…

从To B到AI:产品经理的转型攻略

经过几个月的AI学习之后&#xff0c;我已经对To B产品经理转型AI有了一些自己的理解。 个人认为&#xff0c;想要顺利转型&#xff0c;需要依次经历以下几个思考与学习过程&#xff1a; 认清AI能为产品经理带来的价值&#xff1b;确定AI技术的学习范围&#xff1b;学习AI技术…

关于项目中的内存问题、死锁问题如何定位?——Valgrind

valgrind是如何实现的&#xff1f; 基于仿真方式 在实际处理器的基础上仿真一个虚拟处理器&#xff0c;使应用程序运行于这个虚拟处理器之上&#xff0c;从而进行监视分析。 core dump内存问题定位&#xff1a; 1.无效指针&#xff08;野指针&#xff09; 2.内存泄漏(一般不…

Windows下SDL2创建最简单的一个窗口

先看运行效果 再上代码&#xff1a; #include <stdio.h> #include "SDL.h"int main(int argc, char* argv[]) {// 初始化SDL视频子系统if (SDL_Init(SDL_INIT_VIDEO) -1){printf("Error: %s\n", SDL_GetError());return -1;} // 创建一个窗口SDL_…

再次进阶 舞台王者 第八季完美童模全球赛品牌大使【韩嘉潞】赛场秀场超燃合集!

7月20-23日&#xff0c;2024第八季完美童模全球总决赛在青岛圆满落幕。在盛大的颁奖典礼上&#xff0c;一位才能出众的少女——韩嘉潞&#xff0c;迎来了她舞台生涯的璀璨时刻。 品牌大使——韩嘉潞&#xff0c;以璀璨童星之姿&#xff0c;优雅地踏上完美童模盛宴的绚丽舞台&am…

InstantID模型部署教程

一、介绍 InstantID 是由 InstantX 团队、小红书公司和北京大学联合开发的一项前沿技术&#xff0c;旨在实现零样本身份保持生成&#xff0c;仅需单张图像即可支持多种下游任务&#xff0c;可以在几秒钟内实现零样本身份保留生成。 InstantID 以其独特的无需微调方式&#xf…

Anolis OS 8.8 CentOS8离线安装mysql-8.0.9

下载mysql安装包&#xff1a; mysql下载地址 在Linux系统中&#xff0c;mysql的安装包除了要区分系统和cpu架构之外&#xff0c;还区分安装方式&#xff0c;下载不同的包&#xff0c;安装方式也完全不一样&#xff0c;安装完成后的效果也完全不一样。 我之前下载的包按照官方…

Zabbix企业级应用案列

随着业务的越发复杂&#xff0c;对软件系统的要求越来越高&#xff0c;这意味着我们需要随时掌控系统的运行情况。因此&#xff0c;对系统的实时监控以及可视化展示&#xff0c;就成了基础架构的必须能力。 一、zabbix可视化 1.Grafana 简介 Grafana 是一个开源的指标量监测和…

汽车保养维修|基于java的汽车保养系统小程序(源码+数据库+文档)

汽车保养系统小程序 目录 基于java的汽车保养系统小程序 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道师&#xff0c;阿里云…

简单聊聊bait文件

场景&#xff1a;业务同事发现某云主机部署了企业主机安全&#xff0c;在该主机上发现了一个诱饵文件&#xff0c;显示注意&#xff1a;此文件是诱饵文件&#xff0c;用于防止重要文件被病毒加密。请勿修改或删除此文件。 解决方法&#xff1a;联系企业主机安全运维同事发现&am…

基于SpringBoot+Vue的小区停车场管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

opencv之图像轮廓(三)--凸包

文章目录 前言获取凸包凸缺陷几何学测试测试轮廓是否是凸形的点到轮廓的距离 形状场景算法比较轮廓轮廓的特征值宽高比ExtentSolidity等效直径&#xff08;Equivalent Diameter&#xff09;方向掩模和像素点使用Numpy函数获取轮廓像素点使用OpenCV函数获取轮廓点 最大值和最小值…

太牛了!AI大佬的课程!吴恩达、李飞飞、李宏毅、Hinton、LeCun...

本文精心梳理了AI顶级大佬教授的人工智能课程&#xff0c;涵盖了深度学习、机器学习等多个领域的前沿内容。 这些课程将引领您深入了解决策树、朴素贝叶斯、逻辑回归、神经网络和深度学习等核心知识点&#xff0c;同时还将探索贝叶斯学习、支持向量机和核方法、聚类、无监督学…