原始碼:http://download.csdn.net/detail/nuptboyzhb/4136686
新增標頭檔及全域變數:
#include<math.h>//數學函數庫的標頭檔
#include<Vfw.h>//增加AVI視頻處理函數的標頭檔
#pragma comment(lib,"Vfw32.lib")//串連庫Vfw32.lib
#pragma comment(lib,"Winmm.lib")//連結庫
//定義AVI視頻處理函數所需的結構體變數
AVISTREAMINFO strhdr;
PAVIFILE pfile;
PAVISTREAM ps;
PAVISTREAM pComStream;
AVICOMPRESSOPTIONS pCompressOption;
AVICOMPRESSOPTIONS FAR * opts[1] = {&pCompressOption};
HRESULT hr;
int nFrames = 0; //定義視頻中幀的個數
BOOL m_timer=TRUE;//定時器運行狀態標誌
UINT timer_num=0;//標記定時器的名稱
BOOL m_IsPause=FALSE;//是否暫停標誌
增加OnTimer定時器訊息
// TODO: Add your message handler code here and/or call default
if(m_timer)//如果上一次的定時器程式已經運行完,才執行下面的代碼
{
m_timer=FALSE;//本次定時,正在運行,未結束前,不得進行下次運行
CDC* pDeskDC =GetDesktopWindow()->GetDC();//擷取案頭畫布對象
CRect rc;
GetDesktopWindow()->GetClientRect(rc);//擷取螢幕的用戶端區域
CDC memDC;//定義一個記憶體畫布
memDC.CreateCompatibleDC(pDeskDC);//建立一個相容的畫布
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDeskDC,rc.Width(),rc.Height());//建立相容位元影像
memDC.SelectObject(&bmp);//選中位元影像對象
BITMAP bitmap;
bmp.GetBitmap(&bitmap);
memDC.BitBlt(0,0,bitmap.bmWidth,bitmap.bmHeight,pDeskDC,0,0,SRCCOPY);
DWORD size=bitmap.bmWidthBytes*bitmap.bmHeight;//螢幕映像的總像素數
BYTE* lpData = new BYTE[size];//申請一個大小為size的BYTE型數組,用於存放案頭映像的資料
int panelsize = 0; //記錄調色盤大小
if(bitmap.bmBitsPixel<16)//判斷是否為真彩色位元影像
panelsize = (int)pow(2,bitmap.bmBitsPixel*sizeof(RGBQUAD));
BITMAPINFOHEADER *pBInfo = new BITMAPINFOHEADER;//定義位元影像資訊頭結構體
//初始化位元影像資訊頭
pBInfo->biBitCount = bitmap.bmBitsPixel;
pBInfo->biClrImportant = 0;
pBInfo->biCompression = 0;
pBInfo->biHeight = bitmap.bmHeight;
pBInfo->biPlanes = bitmap.bmPlanes;
pBInfo->biSize = sizeof(BITMAPINFOHEADER);
pBInfo->biSizeImage = bitmap.bmWidthBytes*bitmap.bmHeight;
pBInfo->biWidth = bitmap.bmWidth;
pBInfo->biXPelsPerMeter = 0;
pBInfo->biYPelsPerMeter = 0;
BITMAPINFO bInfo;//定義位元影像資訊結構體
bInfo.bmiHeader = *pBInfo;//初始化
GetDIBits(memDC.m_hDC,bmp,0,pBInfo->biHeight,lpData,&bInfo,DIB_RGB_COLORS);
//將映像資料儲存到pdata
if(nFrames == 0)//如果是第一幀
{
CString rate="3";//3幀
CString filename="111.avi";//檔案名稱
AVIFileOpen(&pfile,filename,OF_WRITE | OF_CREATE,NULL);//開啟或建立AVI檔案
memset(&strhdr, 0, sizeof(strhdr));//初始化資訊頭為0
//初始化AVI視頻流資訊結構體
strhdr.fccType = streamtypeVIDEO;
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
strhdr.dwRate = atoi(rate);
strhdr.dwSuggestedBufferSize = pBInfo->biSizeImage;
SetRect(&strhdr.rcFrame,0,0,pBInfo->biWidth,pBInfo->biHeight);
hr = AVIFileCreateStream(pfile,&ps,&strhdr);//建立AVI檔案流
opts[0]->fccType = streamtypeVIDEO;
opts[0]->fccHandler = mmioStringToFOURCC("MSVC", 0);
opts[0]->dwQuality = 7500;
opts[0]->dwBytesPerSecond = 0;
opts[0]->dwFlags = AVICOMPRESSF_VALID || AVICOMPRESSF_KEYFRAMES;
opts[0]->lpFormat = 0;
opts[0]->cbFormat = 0;
opts[0]->dwInterleaveEvery = 0;
AVIMakeCompressedStream(&pComStream,ps,&pCompressOption,NULL);
AVIStreamSetFormat(pComStream,0,pBInfo,sizeof(BITMAPINFOHEADER));
}
hr = AVIStreamWrite(pComStream,nFrames ,1,(LPBYTE)lpData,
pBInfo->biSizeImage,AVIIF_KEYFRAME,NULL,NULL);//將案頭映像資料寫入檔案
nFrames++;//增加一幀
delete []lpData;//釋放記憶體
delete pBInfo ; //釋放記憶體
m_timer=TRUE;//定時器程式可以繼續響應
}
增加錄製按鈕
timer_num=SetTimer(1,100,0);//啟動定時器
m_timer=TRUE;//設定定時器可用
AVIFileInit(); //初始化AVI檔案
增加停止按鈕
if (timer_num)
{
KillTimer(timer_num);
}
m_timer=FALSE;
if (pComStream)
{
AVIStreamClose(pComStream);
}
if (ps)
{
AVIStreamClose(ps);
}
if(pfile != NULL)
AVIFileRelease(pfile);
AVIFileExit();
nFrames =0;
增加暫停按鈕
if(m_IsPause ==FALSE)
{
m_IsPause = !m_IsPause;
if (timer_num)
{
KillTimer(timer_num);
}
}
else
{
m_IsPause = !m_IsPause;
timer_num=SetTimer(1,100,NULL);
}