Win32 SDK实现AVI文件的播放

我先声明一下代码只适用于256色位图,图像大小在33K左右,程序中使用了windows自带的AVI库,所以要正确设置头文件和Lib文件( Vfw.h  Vfw32.lib ),要播放大一点的图像,或者是24位真彩色图像,都需要修改程序。另一点是要播放的AVI文件被我写死了,你需要注意。这只是一个实验性质的程序,但你只要稍微对其进行修改就可以用于实际的项目。另外,我播放的这个视频文件的透明色是粉色,所以如果你发现不能透明,请你注意这一点。如果需要完全理解这段代码,可能对位图结构和位图透明的实现需要了解。

在这里我只附上Play函数的代码。如果代码中有任何错误,就拜托你自己了。

以下这个Play函数只需要你传递一个窗口的句柄就可以,当然你可以增加位置的参数,但我只是把它绘制在窗口的左上角。

INT CAnime::play(HWND hWnd)
{
PAVIFILE aviFile;
INT nAviRet;
TCHAR szFileName[MAX_PATH];
DWORD ret = -1;
m_hDC = GetDC(hWnd);
nAviRet = AVIFileOpen(&aviFile, TEXT("E:\\avi\\DelFile.avi"), OF_READ, NULL); // 要播放的AVI文件

if (nAviRet != AVIERR_OK) {
MessageBox(NULL, TEXT("AVI AVIFileOpen Err"), TEXT("Error"), MB_OK);
goto PLAY_FAIL1;
}


AVIFILEINFO aviInfo;
AVIFileInfo(aviFile, &aviInfo, sizeof(AVIFILEINFO));
DWORD dwImageWidth  = aviInfo.dwWidth;
DWORD dwImageHeight = aviInfo.dwHeight;


PAVISTREAM pStream;
nAviRet = AVIFileGetStream(aviFile, &pStream, streamtypeVIDEO, 0);
if (nAviRet != AVIERR_OK) {
MessageBox(NULL, TEXT("AVI AVIFileGetStream Err"), TEXT("Error"), MB_OK);
goto PLAY_FAIL2;
}


INT iFirstFrame = AVIStreamStart(pStream);
if (iFirstFrame == -1) {
MessageBox(NULL, TEXT("AVI AVIStreamStart Err"), TEXT("Error"), MB_OK);
goto PLAY_FAIL2;
}


INT iNumFrames=AVIStreamLength(pStream);
if (iNumFrames == -1) {
MessageBox(NULL, TEXT("AVI AVIStreamLength Err"), TEXT("Error"), MB_OK);
goto PLAY_FAIL2;
}


PGETFRAME pFrame;
pFrame = AVIStreamGetFrameOpen(pStream, NULL);


HDC hImageDC = CreateCompatibleDC(m_hDC);
// 创建一个目标
HDC hDestDC = CreateCompatibleDC(m_hDC);
HBITMAP hDestBitMap = CreateCompatibleBitmap(m_hDC, dwImageWidth, dwImageHeight);
HBITMAP hOldDestBitMap = (HBITMAP)SelectObject(hDestDC, hDestBitMap);

// 保存背景
HDC hBackDC = CreateCompatibleDC(m_hDC);
HBITMAP hBackBitMap = CreateCompatibleBitmap(m_hDC, dwImageWidth, dwImageHeight);
HBITMAP hOldBackBitMap = (HBITMAP)SelectObject(hBackDC, hBackBitMap);
BitBlt(hBackDC, 0, 0, dwImageWidth, dwImageHeight, m_hDC, 0, 0, SRCCOPY);


// 创建掩码位图
HDC hMaskDC = CreateCompatibleDC(m_hDC);
HBITMAP hMaskBitMap = CreateBitmap(dwImageWidth, dwImageHeight, 1, 1, NULL);
HBITMAP hOldMaskBitMap = (HBITMAP)SelectObject(hMaskDC, hMaskBitMap);
SetBkColor(hImageDC, RGB(0,0,0)); // 设置背景色为黑色


LONG lsize;
BYTE *pBih = new BYTE[34000];// 一幅图像数据大小
for (int i = iFirstFrame;i < iNumFrames; i++) {
lsize = 34000;
AVIStreamReadFormat(pStream, i, pBih, &lsize);
BITMAPINFOHEADER *bih = (BITMAPINFOHEADER *)pBih;
DWORD biSize = bih->biSizeImage;
// 读取图像数据
AVIStreamRead(pStream, i, 1, pBih + lsize, biSize, NULL, NULL);
HBITMAP hBitmap = CreateDIBitmap(m_hDC, 
(BITMAPINFOHEADER*)pBih, 
CBM_INIT, 
(LPBYTE)pBih + lsize,
(LPBITMAPINFO)pBih,
DIB_RGB_COLORS);

SelectObject(hImageDC, hBitmap);

if (i == 0) {
BitBlt(hDestDC, 0, 0, dwImageWidth, dwImageHeight, hImageDC, 0, 0, SRCCOPY);
} else {
// 以下处理为将当前图像与前一幅图像合成
BitBlt(hMaskDC, 0, 0, dwImageWidth, dwImageHeight, hImageDC, 0, 0, SRCCOPY); // 拷贝到hMaskDC
BitBlt(hDestDC, 0, 0, dwImageWidth, dwImageHeight, hMaskDC, 0, 0, SRCAND);
BitBlt(hDestDC, 0, 0, dwImageWidth, dwImageHeight, hImageDC, 0, 0, SRCPAINT);


}


BitBlt(m_hDC, 0, 0, dwImageWidth, dwImageHeight, hBackDC, 0, 0, SRCCOPY); // 描画背景
// 将新的位图透明绘制到背景上
TransparentBlt(m_hDC,0, 0, dwImageWidth, dwImageHeight, hDestDC, 0,0,dwImageWidth, dwImageHeight,
RGB(254,0,254));

Sleep(100);
}


delete[] pBih;
SelectObject(hDestDC, hOldDestBitMap);
SelectObject(hBackDC, hOldBackBitMap);
SelectObject(hMaskDC, hOldMaskBitMap);
DeleteObject(hDestBitMap);
DeleteObject(hBackBitMap);
DeleteObject(hMaskBitMap);

DeleteDC(hBackDC);
DeleteDC(hDestDC);
DeleteDC(hImageDC);
DeleteDC(m_hDC);


AVIStreamGetFrameClose(pFrame);

ret = 0;
PLAY_FAIL2:
if (pStream != NULL)
AVIStreamRelease(pStream);


PLAY_FAIL1:
if (aviFile != NULL)
AVIFileRelease(aviFile);
AVIFileExit();
DeleteFile(szFileName);
return ret;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值