首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

Visual C++ 實現 AVI 視頻幀擷取與 BMP 儲存

     編輯:關於VC++

AVI 檔案結構與操作基礎

AVI (Audio Video Interleave) 是微軟定義的多媒體容器格式,屬於 RIFF 規範。典型 AVI 包含音訊串流與視訊串流,特殊情況下可能含控制軌或 MIDI 軌。雖然播放軟體眾多,但能從視訊串流擷取單一幀並存為 BMP 的工具較少。

AVI API 初始化與釋放

操作 AVI 必須成對呼叫:

  • AVIFileInit() - 程式啟動時初始化 AVI 函式庫
  • AVIFileExit() - 程式結束時釋放資源

若未正確初始化,後續 API 呼叫將失效。

自訂 CAvi 類別設計

封裝 AVI 操作的核心類別:

class CAvi {
public:
    int cy;                    // 影像高度
    int cx;                    // 影像寬度
    BYTE* pData;               // 影像資料緩衝區
    BITMAPINFO* m_pBMI;        // BMP 資訊標頭
    PAVISTREAM pavi;           // 視訊串流介面
    PAVIFILE pfile;            // AVI 檔案介面
    AVIFILEINFO* pfi;          // AVI 檔案資訊

    BOOL AviRead(int mFrame);  // 讀取第 mFrame 幀
    CAvi();                    // 建構式
    CAviCreate(CString& str);  // 以檔名初始化
    virtual ~CAvi();           // 解構式
};

建構式與解構式

CAvi::CAvi() {
    AVIFileInit();             // 初始化 AVI 庫
    cx = cy = 0;
    m_pBMI = NULL;
    pData = NULL;
    pfi = NULL;
}

CAvi::~CAvi() {
    AVIFileExit();             // 釋放 AVI 庫
    if (pData) { delete[] pData; pData = NULL; }
    if (m_pBMI) { delete m_pBMI; m_pBMI = NULL; }
    if (pfi) { delete pfi; pfi = NULL; }
}

CAviCreate - 檔案開啟與資訊讀取

CAvi::CAviCreate(CString& str) {
    HRESULT hr;
    pfi = new AVIFILEINFO;

    // 開啟 AVI 檔案
    hr = AVIFileOpen(&pfile, str, OF_READ, NULL);

    // 取得檔案資訊 (寬、高等)
    hr = AVIFileInfo(pfile, pfi, sizeof(AVIFILEINFO));
    cx = pfi->dwWidth;
    cy = pfi->dwHeight;

    // 取得視訊串流
    hr = AVIFileGetStream(pfile, &pavi, streamtypeVIDEO, 0);

    // 建立 BMP 資訊標頭 (24-bit RGB)
    m_pBMI = new BITMAPINFO;
    m_pBMI->bmiHeader.biBitCount = 24;
    m_pBMI->bmiHeader.biCompression = BI_RGB;
    m_pBMI->bmiHeader.biWidth = cx;
    m_pBMI->bmiHeader.biHeight = cy;
    m_pBMI->bmiHeader.biPlanes = 1;
    m_pBMI->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    m_pBMI->bmiHeader.biSizeImage = cx * cy * 3;

    // 配置影像資料緩衝區
    pData = new BYTE[cx * cy * 3];
}

AviRead - 讀取指定幀

BOOL CAvi::AviRead(int mFrame) {
    HRESULT hr = AVIStreamRead(pavi, mFrame, 1, pData, cx * cy * 3, NULL, NULL);
    return (hr == 0) ? TRUE : FALSE;
}

BMP 檔案儲存

取得 pData (像素資料) 與 m_pBMI (標頭) 後,可依 BMP 檔案格式寫入磁碟。需建立 BITMAPFILEHEADER,計算檔案大小與偏移量,依序寫入:檔案標頭、資訊標頭、像素資料。完整儲存邏輯請參考「Visual C++6.0 開發灰度位圖處理」。

編譯環境與驗證

  • 作業系統:Windows 2000
  • 開發工具:Visual C++ 6.0
  • 編譯狀態:通過
  • 執行狀態:正常

關鍵 API 對照表

API 函式用途
AVIFileInit / AVIFileExit函式庫初始化/釋放
AVIFileOpen開啟 AVI 檔案
AVIFileInfo取得檔案屬性 (寬、高、幀數等)
AVIFileGetStream取得指定類型串流 (streamtypeVIDEO)
AVIStreamRead讀取指定幀資料到緩衝區
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved