用SampleGrabber为实时采集视频叠加文字标识
来源:互联网 发布:怎么查看端口是否开放 编辑:程序博客网 时间:2024/06/07 01:02
转载自:http://blog.csdn.net/xiaolei05/article/details/6595642
DirectShow实时采集的视频,在采集filter的输出端子与下一级处理filter之间,添加一个SampleGrabber,可以实现为视频打上logo或者文字标识的功能。
通过IFilterGraph::AddFilter()将SampleGrabber添加到graph中后,在连接之前,首先需要通过ISampleGrabber::SetMediaType()设置SampleGrabber的媒体类型。
因为需要画图,所以需要要将SampleGrabber的媒体类型设置如下:(以下代码段为采用directshow.net的C#语言编写)
int hr;
AMMediaType media = new AMMediaType();
// Set the media type to Video/RGB24
media.majorType = MediaType.Video;
media.subType = MediaSubType.RGB24;
media.formatType = FormatType.VideoInfo;
hr = sampGrabber.SetMediaType( media );
DsError.ThrowExceptionForHR( hr );
DsUtils.FreeAMMediaType(media);
设置subType为RGB24,则可以从SampleGrabber抓出的sample中,得到每一帧图像的类型为RGB24的Bitmap,在这个Bitmap上绘制logo或者文字,就可以实现文字叠加的功能。
当然,也可以设置subType为其他位图类型,但是考虑到某些位图类型(比如ARGB32),采集设备可能不支持,所以推荐使用RGB24。
实现ISampleGrabberCB.BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen),在这个回调函数中对采集设备传过来的帧图像进行绘制,下面代码获得帧的Bitmap:
Bitmap theFrame = new Bitmap(m_videoWidth, m_videoHeight, m_stride,
PixelFormat.Format24bppRgb, pBuffer);
注意由于采集是至上而下扫描,而缺省的Bitmap是至下而上扫描,所以这时得到的表示帧的Bitmap是上下颠倒的,然而并不能使用图像处理函数直接将theFrame再颠倒过来,那样的话,改动不能作用到filter中传输的sample上,估计可能是因为rotate等图像处理函数会导致新生成一个位图。解决方法是新建一个位图用来绘制需要叠加的信息,再将新位图颠倒过来,绘制到theFrame上。
另外,为了减少系统消耗,新建的位图可以控制大小,只需容纳要叠加的文字或图片宽度即可。代码如下:
// 信息字符距离帧图像边界的宽度
const int INFO_BORDER_WIDTH = 5;
Graphics gFrame = Graphics.FromImage(theFrame);
// 获得信息字符串
string s = "地点\n";
s += DateTime.Now.ToString();
// 获得绘制该字符串所需的面积
Font drawFont = new Font("Arial", 8);
SizeF strDim = gFrame.MeasureString(s, drawFont);
// 若帧图像比信息图像小,则不绘制信息
if (m_videoHeight < strDim.Height + INFO_BORDER_WIDTH + INFO_BORDER_WIDTH
|| m_videoWidth < strDim.Width + INFO_BORDER_WIDTH + INFO_BORDER_WIDTH)
{
gFrame.Dispose();
return;
}
// 新建用于绘制信息的小图片
Bitmap bimInfo = new Bitmap((int)strDim.Width + 1, (int)strDim.Height + 1);
Graphics gInfo = Graphics.FromImage(bimInfo);
gInfo.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
SolidBrush drawBrush = new SolidBrush(Color.White);
gInfo.DrawString(s, drawFont, drawBrush, new Point(0, 0));
// 将绘制信息的小图片上下翻转
bimInfo.RotateFlip(RotateFlipType.RotateNoneFlipY);
// 将小图片绘制到帧图像上
Point bimInfoPoint = new Point(INFO_BORDER_WIDTH, m_videoHeight - INFO_BORDER_WIDTH - (int)strDim.Height);
gFrame.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
gFrame.DrawImage(bimInfo, bimInfoPoint);
// 释放对象
drawFont.Dispose();
drawBrush.Dispose();
gInfo.Dispose();
bimInfo.Dispose();
gFrame.Dispose();
这个方法实现的文字叠加有一个小问题,就是当文字颜色与帧底色接近时,文字边缘会出现彩色,估计是DrawImage的算法导致的,目前我还不知道如何解决。
- 用SampleGrabber为实时采集视频叠加文字标识
- 用SampleGrabber为实时采集视频叠加文字标识
- 用SampleGrabber为实时采集…
- 视频叠加文字
- Android 用MediaRecorder实时视频采集
- Android 实时视频采集
- android 实时视频采集
- Android实时视频采集方案
- 视频上叠加汉字点阵文字
- android开发,通过摄像头实时采集视频并使用MediaCodec硬编码为H264
- 【流媒體】Android 实时视频采集方案一
- Android 实时视频采集—Cameara
- ffmpeg+ffserver实时视频采集流媒体转发
- Android 实时视频采集—MediaRecoder录制
- iOS音视频实时采集硬件编码
- V4L2视频采集及H264实时压缩
- Android 实时视频采集—Camera预览采集
- Android 实时视频采集—Cameara预览采集
- 希望能记录每天成长的我
- C语言再学习 -- 运算符与表达式
- Message Flood(字典树)
- 一,数据库设计范式(MySQL为例)
- CURL是什么?
- 用SampleGrabber为实时采集视频叠加文字标识
- 笔记--ThinkPHP模板文件
- 扩展
- C编程语言嵌入Lua的用法
- 集群模式下Zookeeper的安装
- RSA加密演算法
- 一句Python,一句R︱numpy、array——高级matrix
- 62. Unique Paths
- 好的博客分享