您的位置:首页 > 其它

使用GDI实现视频字幕及特效

2016-12-18 12:14 190 查看
每周一记!

最近使用GDI实现了给视频添加字幕以及字幕出场和结束特效的功能,特此记录一下实现过程,注意这里的视频字幕是直接写入视频文件的。

实现字幕的基本思路:首先创建一个设备位图,用DrawText函数往位图里面写字,然后取出位图数据与原视频解码出来的图片数据进行像素混合,这样就实行了添加字幕功能。

创建设备位图代码如下:

int width = 800;
int height = 600;
//创建兼容性hdc
HDC hDcMen = CreateCompatibleDC(hdc);
//创建宽高固定的位图设备
HBITMAP hBitmap = CreateCompatibleBitmap(hDcMen, width, height);
//替换位图设备
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hDcMen, hBitmap );


这样我们就创建了一个800*600的位图设备,然后往里面写入字幕。

TCHAR szText[] = TEXT("第一条字幕");
//设置绘制区域
RECT rc = { 0,0,800,600 };
DrawText(hDcMen, szText, 5, &rc, DT_CENTER);


这里可以使用CreateFont函数来设置绘制的字体,然后替换掉hDcMen里的字体设备,就可以写自己想要的字体了。想要改变颜色的话调用SetTextColor函数设置字体颜色。同时DrawText函数可以用DT_CALCRECT标志来事先计算文字的矩形区域,然后再调用DrawText函数绘制字幕。注意DrawText是可以自动换行的,只需设置DT_EDITCONTROL | DT_WORDBREAK;

到了这里我们已经得到了写入字幕的位图设备,取出里面的像素数据。

//申请内存
unsigned char * pData = new unsigned char[800 * 600 * 4];
//获取位图数据
long ret = GetBitmapBits(hBitmap, 800 * 400 * 4, pData);


然后将pData里的数据和视频解码的图片进行RGB混合,这里我就不贴代码了。

接下来说一下实现字幕的淡入淡出特效,主要通过改变底图和上层图片的透明度来实现,因为GDI绘制是没有透明度那一位的,我们需要手动设置一个透明度,并让它在开始和结束动态变化,实现淡入淡出。

//透明度
float fAlpha = 0.0f;
//RGB混合
pBack[0] = pBack[0] * (1 - fAlpha) + pFront[0] * fAlpha;
pBack[1] = pBack[1] * (1 - fAlpha) + pFront[1] * fAlpha;
pBack[2] = pBack[2] * (1 - fAlpha) + pFront[2] * fAlpha;


pBack是底图数据,pFront是字幕图片数据,我们只要在字幕开始显示时,将fAlpha变量从0.0递增到1.0,播放起来就有一个慢慢显现的效果,在字幕显示快结束的时候将fAlpha从1.0递减到0.0,就有了淡出效果。

这个特效是比较简单的,我们可以传入一个float变量代表字幕显示的程度,从0%到100%。可以用上面的fAlpha来代替。这样实现从左到右显示,以及从上到下显示就很简单了,只是根据显示程度来调整混合透明度就可以了。留给大家自己发挥想象力吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gdi 字幕 特效 视频