如何由 AVI 檔案中將影像frame讀出來 |
|
cmf
尊榮會員 發表:84 回覆:918 積分:1032 註冊:2002-06-26 發送簡訊給我 |
Usage (使用範例) AVI2BMP.bpr
#include "vfw.h" // for video bool Frame2TImage(PAVISTREAM *gapavi,AVISTREAMINFO *avis,long miniSecond,TImage *Image1);// 從影像串流中取出相對應時間的Frame, 並秀在指定TImage的Canvas 上
bool GetVideoStream(char *szFile,PAVISTREAM *gapavi,AVISTREAMINFO *avis); // 由 AVI 檔中取出影像串流 void __fastcall TForm1::Button3Click(TObject *Sender)
{
PAVISTREAM gapavi;
AVISTREAMINFO avis; // 取出 Video Stream
GetVideoStream("c:\\Capture.avi",&gapavi,&avis);
// 秀出指定的frame
Frame2TImage(&gapavi,&avis,5000,Image1); } ================================== AVI Utility ====================================
1. 由 AVI 檔中取出影像串流, GetVideoStream
2. 從影像串流中取出相對應時間的Frame, 並秀在指定TImage的Canvas 上, Frame2TImage
==================================================================================== //---------------------------------------------------------------------------
/*
由 AVI 檔中取出影像串流
bool GetVideoStream(char *szFile,PAVISTREAM *gapavi,AVISTREAMINFO *avis)
ex:
PAVISTREAM gapavi;
AVISTREAMINFO avis; // 取出 Video Stream
GetVideoStream("c:\\Capture.avi",&gapavi,&avis);
*/
bool GetVideoStream(char *szFile,PAVISTREAM *gapavi,AVISTREAMINFO *avis)
{
//1 Initial the AVI library
AVIFileInit(); //2 Open an AVI-file HRESULT hr;
PAVIFILE pfile;
// 讀取avi檔案
hr = AVIFileOpen(&pfile,szFile , 0, 0L); if (hr != 0)
{
return false;
} //3 Getting an AVI stream
//PAVISTREAM gapavi; // for storage the frames of AVI
int gcpavi;
AVIFileGetStream(pfile, gapavi, 0L, 0); // 把得到的 Stream interface放在gapavi中
//4. Get the stream information
//AVISTREAMINFO avis;
AVICOMPRESSOPTIONS gaAVIOptions;
LPAVICOMPRESSOPTIONS galpAVIOptions; // Stream header的資訊放在 avis中
AVIStreamInfo(*gapavi, avis, sizeof(*avis));
galpAVIOptions = &gaAVIOptions;
// 把 gaAVIOptions的內容清為0
_fmemset(galpAVIOptions, 0, sizeof(AVICOMPRESSOPTIONS));
// 取出該 stream 的多媒體型態放在相對應的gaAVIOptions陣列中
galpAVIOptions->fccType = avis->fccType; switch(avis->fccType) {
case streamtypeVIDEO:
galpAVIOptions->dwFlags = AVICOMPRESSF_VALID | AVICOMPRESSF_KEYFRAMES | AVICOMPRESSF_DATARATE;
galpAVIOptions->fccHandler = 0;
galpAVIOptions->dwQuality = (DWORD)ICQUALITY_DEFAULT;
galpAVIOptions->dwKeyFrameEvery = (DWORD)-1; // Default
galpAVIOptions->dwBytesPerSecond = 0;
galpAVIOptions->dwInterleaveEvery = 1;
break;
default:
break;
}
return true;
}
/* 從影像串流中取出相對應時間的Frame, 並秀在指定TImage的Canvas 上
bool Frame2TImage(PAVISTREAM *gapavi,AVISTREAMINFO *avis,long miniSecond,TImage *Image1) ex:
// 秀出指定的frame
Frame2TImage(&gapavi,&avis,5000,Image1);
*/
bool Frame2TImage (PAVISTREAM *gapavi,AVISTREAMINFO *avis,long miniSecond,TImage *Image1)
{
PGETFRAME gapgf; // GetFrame物件
//5. 對指定的 gapavi video stream 進行解壓縮,傳回 GetFrame物件放在gapgf中
if (avis->fccType == streamtypeVIDEO) {
gapgf = AVIStreamGetFrameOpen(*gapavi, NULL);
if (gapgf == NULL)
return false;
}
//6. 對指定的時間(2th) 計算相對應的frame
LONG lFrame;
lFrame = AVIStreamTimeToSample(*gapavi, miniSecond); //8. Get a video frame
BYTE abFormat[1024]; LPBITMAPINFOHEADER lpbi; // <----- the frame data
lpbi = (LPBITMAPINFOHEADER)abFormat; // 指定 lpbi的位址
// 傳回 Video frame的位址放在 lpbi
lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(gapgf,lFrame ); // 10. Paint Video HBITMAP hBitmap;
hBitmap=CreateDIBitmap( GetDC(NULL),lpbi,CBM_INIT,(BYTE *)lpbi+40,(BITMAPINFO *)lpbi,DIB_RGB_COLORS);
HBITMAP2TImage(hBitmap,Image1); return true;
}
------
︿︿ |
WhiteFang
一般會員 發表:9 回覆:23 積分:6 註冊:2002-11-22 發送簡訊給我 |
引言: /* 從影像串流中取出相對應時間的Frame, 並秀在指定TImage的Canvas 上 bool Frame2TImage(PAVISTREAM *gapavi,AVISTREAMINFO *avis,long miniSecond,TImage *Image1) ex: // 秀出指定的frame Frame2TImage(&gapavi,&avis,5000,Image1); */ bool Frame2TImage (PAVISTREAM *gapavi,AVISTREAMINFO *avis,long miniSecond,TImage *Image1) { PGETFRAME gapgf; // GetFrame物件 //5. 對指定的 gapavi video stream 進行解壓縮,傳回 GetFrame物件放在gapgf中 if (avis->fccType == streamtypeVIDEO) { gapgf = AVIStreamGetFrameOpen(*gapavi, NULL); if (gapgf == NULL) return false; } //6. 對指定的時間(2th) 計算相對應的frame LONG lFrame; lFrame = AVIStreamTimeToSample(*gapavi, miniSecond); //8. Get a video frame BYTE abFormat[1024]; LPBITMAPINFOHEADER lpbi; // <----- the frame data lpbi = (LPBITMAPINFOHEADER)abFormat; // 指定 lpbi的位址 // 傳回 Video frame的位址放在 lpbi lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(gapgf,lFrame ); // 10. Paint Video HBITMAP hBitmap; hBitmap=CreateDIBitmap( GetDC(NULL),lpbi,CBM_INIT,(BYTE *)lpbi 40,(BITMAPINFO *)lpbi,DIB_RGB_COLORS); HBITMAP2TImage(hBitmap,Image1); return true; }最後那一個函示"HBITMAP2TImage"是那個函示庫的呢?help也找不到! |
WhiteFang
一般會員 發表:9 回覆:23 積分:6 註冊:2002-11-22 發送簡訊給我 |
自問自答,我找到了!麻煩轉貼的時候完整一點! [BCB] 19
/* 將一個 HBITMAP 型態的Bmp 秀在指定TImage的Canvas 上
Name: BITMAP2TImage(HBITMAP Bitmap1,TImage *Image1)
Usage:
HBITMAP2TImage(hBitmap,Image1);
*/
bool HBITMAP2TImage(HBITMAP hBitmap,TImage *Image1)
{
BITMAP bitmap;
Graphics::TBitmap *Bitmap1=new Graphics::TBitmap();
Bitmap1->Handle=hBitmap;
// 取得 Bmp 的 Width & Height
GetObject(hBitmap,sizeof(BITMAP),&bitmap);
Image1->Width=bitmap.bmWidth;
Image1->Height=bitmap.bmHeight; // 把 Bitmap 畫在 Image1上
Image1->Canvas->Draw(0,0,Bitmap1);
delete Bitmap1;
Image1->Visible=true;
Image1->Repaint();
return true;
}
|
taishyang
站務副站長 發表:377 回覆:5490 積分:4563 註冊:2002-10-08 發送簡訊給我 |
WhiteFang您好: 感謝您的補充~~
avi轉bmp的範例也可以參考下面的連結
http://netcity1.web.hinet.net/userdata/nep2314/
順心< >< > 發表人 - taishyang 於 2003/03/28 20:57:15
|
WhiteFang
一般會員 發表:9 回覆:23 積分:6 註冊:2002-11-22 發送簡訊給我 |
引言: WhiteFang您好: 感謝您的補充~~ avi轉bmp的範例也可以參考下面的連結 http://netcity1.web.hinet.net/userdata/nep2314/ 順心< >< > 發表人 - taishyang 於 2003/03/28 20:57:15謝謝您提供的網頁,我用過但似乎無法讀取我的avi 請問一下喔!我的avi是DV擷取的,有沒有那個元件或API可以讀取呢? 還是只有用ActiveX? |
taishyang
站務副站長 發表:377 回覆:5490 積分:4563 註冊:2002-10-08 發送簡訊給我 |
WhiteFang您好:
引言: 我用過但似乎無法讀取我的avi請問一下喔!我的avi是DV擷取的,有沒有那個元件或API可以讀取呢?還是只有用ActiveX?讀取avi檔可參考 void __fastcall TForm1::FormCreate(TObject *Sender) { MediaPlayer1->Display=Form1; MediaPlayer1->Open(); MediaPlayer1->FileName="c:\\windoes\\clock.avi"; }或用Animate1元件也可以 我覺得您的問題可能跟檔案格式有關,我猜可能是撥放軟體不支援吧 你可以參考下面連結 < href="http://delphi.ktop.com.tw/topic.php?TOPIC_ID=26810">http://delphi.ktop.com.tw/topic.php?TOPIC_ID=26810 應該可以解決< >< > 發表人 - taishyang 於 2003/04/01 22:03:03 |
WhiteFang
一般會員 發表:9 回覆:23 積分:6 註冊:2002-11-22 發送簡訊給我 |
引言: WhiteFang您好: 讀取avi檔可參考那再請問一下,Media Player ActiveX可以將一個個的Frame擷取下來嗎?void __fastcall TForm1::FormCreate(TObject *Sender) { MediaPlayer1->Display=Form1; MediaPlayer1->Open(); MediaPlayer1->FileName="c:\\windoes\\clock.avi"; }或用Animate1元件也可以 我覺得您的問題可能跟檔案格式有關,我猜可能是撥放軟體不支援吧 你可以參考下面連結 < href="http://delphi.ktop.com.tw/topic.php?TOPIC_ID=26810">http://delphi.ktop.com.tw/topic.php?TOPIC_ID=26810 應該可以解決< >< > 發表人 - taishyang 於 2003/04/01 22:03:03 |
kikikoko
一般會員 發表:4 回覆:8 積分:2 註冊:2003-05-16 發送簡訊給我 |
引言: Usage (使用範例) AVI2BMP.bpr #include "vfw.h" // for video bool Frame2TImage(PAVISTREAM *gapavi,AVISTREAMINFO *avis,long miniSecond,TImage *Image1);// 從影像串流中取出相對應時間的Frame, 並秀在指定TImage的Canvas 上 bool GetVideoStream(char *szFile,PAVISTREAM *gapavi,AVISTREAMINFO *avis); // 由 AVI 檔中取出影像串流 void __fastcall TForm1::Button3Click(TObject *Sender) { PAVISTREAM gapavi; AVISTREAMINFO avis; // 取出 Video Stream GetVideoStream("c:\\Capture.avi",&gapavi,&avis); // 秀出指定的frame Frame2TImage(&gapavi,&avis,5000,Image1); }cmf 您好 我試著將Frame2TImage(&gapavi,&avis,5000,Image1);改成 while(i<20000) { Frame2TImage(&gapavi,&avis,i,Image1); i=i+120; } 結果只能撥原本avi檔的部分,若i=i+120改成i=i+600則可全部撥完。 不知是為什麼?還有請問要如何知道avi檔的總時間呢? 發表人 - kikikoko 於 2003/05/17 04:29:00 |
cmf
尊榮會員 發表:84 回覆:918 積分:1032 註冊:2002-06-26 發送簡訊給我 |
|
clarkkent
初階會員 發表:29 回覆:83 積分:32 註冊:2003-01-23 發送簡訊給我 |
各位先進及cmf大哥您好:
翻看以前的文章找到了這篇
有點問題想請教 Frame2TImage(&gapavi,&avis,5000,Image1);
撥放5秒的AVI FRAME 計算出多少BMP圖 張數 顯示於IMAGE1 上面 以上是cmf大哥的解釋 請問,這行程式是適用在任何長度的avi嗎?(ex:一秒、七秒…)
另外如果想將每個frame存成一張bmp,應該是在哪個step進行呢? 謝謝您 新手上路,請多指教
如果此文章違反版規 還請版主告知並刪除
Just do it
------
JUST DO IT |
even
一般會員 發表:12 回覆:17 積分:5 註冊:2003-07-18 發送簡訊給我 |
|
jchuang
一般會員 發表:41 回覆:36 積分:15 註冊:2003-08-08 發送簡訊給我 |
|
sunmi629
一般會員 發表:5 回覆:6 積分:2 註冊:2003-07-04 發送簡訊給我 |
|
jane7374015
一般會員 發表:5 回覆:3 積分:1 註冊:2005-06-08 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |