當程式用capCapture不斷地抓入影像資料時,這個資料其實是以
PVEDIOHDR的結構放在記憶體之中, 這是一頁一頁的影像資料, 攝影機每抓好一頁就會啟動
VidoeCallBackProc一次.
而若你要壓縮這個影像資料, 可以叫用ICCompress這個函數(Windows SDK)。
但是叫用之前要先用
hic := ICOpen(ICTYPE_VIDEO, mmioFOURCC('M','P','4','2'), ICMODE_FASTCOMPRESS);
來設定用那個driver來壓縮
上面的例子就是設定為MPEG4。
你注意到了其中有一個mmioFourCC('M','P','4','2')參數了嗎?(其它的是constant, 參考SDK說明文件)
這是一個VFW的函數, 設定一個4碼的代碼. 每一個驅動程式都有一個代碼, 例如DIVX就是'D','I','V','X'
設定完了之後, 再用
ICCompressBegin(hIC, @EncBiIn, @EncBiOut);
啟始之後, 就可以用
ICCompress(hic, dwFlags, @EncBiOut.bmiHeader, CodeDest, @EncBiIn.bmiHeader, CodeSrc, Nil, @dwFlags, FrameNo, 0, 0, Nil, Nil);
來開始壓縮每一個影像頁(由上例中, 待壓縮的資料是放在CodeSrc參數所指向的位址)
壓縮完之後, 壓縮的結果也在記憶體中(CodeDest所指向的位址).
對了, EnbiOUTBMI的內容也要先設定,(一樣可查SDK文件)
用完了,再叫用
ICCompressEnd(hic);
ICClose(hic);
來結朿壓縮函式.
解壓縮則是用ICDecopress
其實真的很麻煩喔......................................
範例片段:
宣告
EncBiIn, EncBiOut: BITMAPINFO;
執行
VideoW := 352;
VideoH := 288;
CodeSrc := PChar(AllocMem(VideoW*VideoH*3+64));
CodeDest := PChar(AllocMem(VideoW*VideoH*3+64));
// hic := ICOpen(ICTYPE_VIDEO, mmioFOURCC('D','I','V','X'), ICMODE_FASTCOMPRESS);
hic := ICOpen(ICTYPE_VIDEO, mmioFOURCC('M','P','4','2'), ICMODE_FASTCOMPRESS);
if hic=0 then MessageBox(Handle, 'Error Init compressor', '', MB_OK);
EncBiIn.bmiHeader.biSize := sizeof(BITMAPINFOHEADER);
EncBiIn.bmiHeader.biCompression := BI_RGB;
EncBiIn.bmiHeader.biWidth := VideoW;
EncBiIn.bmiHeader.biHeight := VideoH;
EncBiIn.bmiHeader.biPlanes := 1;
EncBiIn.bmiHeader.biBitCount := 24;
EncBiIn.bmiHeader.biSizeImage := EncBiIn.bmiHeader.biWidth*EncBiIn.bmiHeader.biHeight*EncBiIn.bmiHeader.biPlanes*(EncBiIn.bmiHeader.biBitCount div 8);
EncBiIn.bmiHeader.biXPelsPerMeter := 0;
EncBiIn.bmiHeader.biYPelsPerMeter := 0;
EncBiIn.bmiHeader.biClrUsed := 0;
EncBiIn.bmiHeader.biClrImportant := 0;
EncBiOut.bmiHeader.biSize := sizeof(BITMAPINFOHEADER);
// EncBiOut.bmiHeader.biCompression := mmioFOURCC('D','I','V','X');
EncBiOut.bmiHeader.biCompression := mmioFOURCC('M','P','4','2');
EncBiOut.bmiHeader.biWidth := VideoW;
EncBiOut.bmiHeader.biHeight := VideoH;
EncBiOut.bmiHeader.biPlanes := 1;
EncBiOut.bmiHeader.biBitCount := 24;
EncBiOut.bmiHeader.biSizeImage := EncBiIn.bmiHeader.biWidth*EncBiIn.bmiHeader.biHeight*EncBiIn.bmiHeader.biPlanes*(EncBiIn.bmiHeader.biBitCount div 8);
EncBiOut.bmiHeader.biXPelsPerMeter := 0;
EncBiOut.bmiHeader.biYPelsPerMeter := 0;
EncBiOut.bmiHeader.biClrUsed := 0;
EncBiOut.bmiHeader.biClrImportant := 0;
hVideoWnd := capCreateCaptureWindow('capture', WS_CHILD or WS_VISIBLE,
Panel1.Left+1, Panel1.Top+1,
VideoW, VideoH, Handle, 0);
capSetCallbackOnVideoStream(hVideoWnd, @VideoCallbackProc);