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

来源:互联网 发布:vue 源码 编辑:程序博客网 时间:2024/06/11 21:14

每周一记!
最近使用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来代替。这样实现从左到右显示,以及从上到下显示就很简单了,只是根据显示程度来调整混合透明度就可以了。留给大家自己发挥想象力吧!

1 0
原创粉丝点击