全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4996
推到 Plurk!
推到 Facebook!

如何由 AVI 檔案中將影像frame讀出來

 
cmf
尊榮會員


發表:84
回覆:918
積分:1032
註冊:2002-06-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-02-20 10:20:17 IP:61.218.xxx.xxx 未訂閱
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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-03-28 20:15:03 IP:163.28.xxx.xxx 未訂閱
引言: /* 從影像串流中取出相對應時間的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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-03-28 20:29:03 IP:163.28.xxx.xxx 未訂閱
自問自答,我找到了!麻煩轉貼的時候完整一點! [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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-03-28 20:54:14 IP:140.135.xxx.xxx 未訂閱
WhiteFang您好:       感謝您的補充~~    avi轉bmp的範例也可以參考下面的連結    http://netcity1.web.hinet.net/userdata/nep2314/ 順心< >< > 發表人 - taishyang 於 2003/03/28 20:57:15
WhiteFang
一般會員


發表:9
回覆:23
積分:6
註冊:2002-11-22

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-03-29 14:30:50 IP:163.28.xxx.xxx 未訂閱
引言: 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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-04-01 18:45:57 IP:61.231.xxx.xxx 未訂閱
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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-04-03 02:33:33 IP:163.28.xxx.xxx 未訂閱
引言: WhiteFang您好: 讀取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
那再請問一下,Media Player ActiveX可以將一個個的Frame擷取下來嗎?
kikikoko
一般會員


發表:4
回覆:8
積分:2
註冊:2003-05-16

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-05-16 23:42:23 IP:218.168.xxx.xxx 未訂閱
引言: 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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-05-17 00:18:03 IP:61.70.xxx.xxx 未訂閱
        Frame2TImage(&gapavi,&avis,5000,Image1);    其中的 5000 單位為 千分之1秒 也就是 5秒    也就是撥放5秒的AVI FRAME 計算出多少BMP圖 張數  顯示於IMAGE1 上面        僅供參考,歡迎繼續發言願以此功德 莊嚴佛淨土 上報四重恩 下濟三塗苦 若有見聞者 悉發菩提心 盡此一報身 同生極樂國
------
︿︿
clarkkent
初階會員


發表:29
回覆:83
積分:32
註冊:2003-01-23

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-06-30 16:40:27 IP:61.59.xxx.xxx 未訂閱
各位先進及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

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-07-30 15:51:44 IP:210.202.xxx.xxx 未訂閱
我有問題.. 要取出
jchuang
一般會員


發表:41
回覆:36
積分:15
註冊:2003-08-08

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-08-18 13:44:58 IP:163.28.xxx.xxx 未訂閱
您好: 我是將下列的程式改成如下    Frame2TImage(&gapavi,&avis,0,Image1);    for(i=34;i=<10000;i =33) { Frame2TImage(&gapavi,&avis,i,Image1); } 一秒鐘有30個frame,又因為我想讀出每一個frame 可是不 管我的avi有多長,最多都只可以讀出74個frame 這是為什麼呢?? 新手上路
------
新手上路
sunmi629
一般會員


發表:5
回覆:6
積分:2
註冊:2003-07-04

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-12-18 15:31:06 IP:61.56.xxx.xxx 未訂閱
請問有這支程式的範例可以下載來參考嗎? 謝謝~~~
jane7374015
一般會員


發表:5
回覆:3
積分:1
註冊:2005-06-08

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-10-22 18:18:02 IP:211.74.xxx.xxx 未訂閱
請問~有可以支援avi以外的嗎?
系統時間:2024-04-27 18:58:33
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!