VFWで取得したAVIのフレーム静止画をクリップボードに転送するには?


VC++超初心者の初級VBプログラマ  2006-12-05 09:19:52  No: 63828

Video For WindowsのLPVOID AVIStreamGetFrame(pget, lPos)で取得した
フレームの画像をDIB形式でクリップボードに送りたいのですが、その方法
をご教授ください。
  AVIStreamGetFrameでは、BITMAPINFOHEADERへのポインタが戻ってくる
ようですが、WindowsDIBファイルでいうBITMAPFILEHEADERを除いたあとの
部分がメモリに格納されているのでしょうか?(パックDIBて何?)
  クリップボードへの転送にはSetClipboardData(uFormat, hMem)が使えそ
うなのですが、第2引数に何を入れたらよいのかわからないのです。
よろしくお願いします。


VC++超初心者の初級VBプログラマ  2007-01-07 10:37:30  No: 63829

投稿者です。

以下のサイトの情報を参考にして、目的のプログラムを作って
みました。なんとか目的を達しているようにも思いますが、
いまいち自信がありません。アドバイスいただければ幸いです。

Video for Windows関係の記事
http://www.ecoop.net/coop/vfw/avi.html
http://www.ecoop.net/coop/vfw/aviapi.html

Clipboard関係の記事
http://wisdom.sakura.ne.jp/system/winapi/win32/win90.html

開発環境  Windows2000ProSP4 VC++6.0
Win32 Console Applicationで作成。エラー処理部分は冗長に
なりそうなので省きました。
実際の利用は、下記内容をDLLにしてVBから利用する予定です。

---------------------------------------------
#include "stdafx.h"
#include <windows.h>  //windowsAPIヘッダ
#include <vfw.h>  //Video For Windows用ヘッダ

int openAVI(const char* filename);
int readAVI2CB(long frame);
int closeAVI(void);

PAVIFILE PAvi;  //AVIファイルインタフェースへのポインタ
PAVISTREAM PStm;//AVIストリームインタフェースへのポインタ
PGETFRAME PFrm;  //GetFrameオブジェクトへのポインタ

int main(int argc, char* argv[])
{
  openAVI("c:\\test.avi\0");
  readAVI2CB(1);  //ためしにフレームNo.1をクリップボードへ
  closeAVI();
  return 0;
}

//AVIを開いてフレームにアクセスできるところまでをまとめる。
int openAVI(const char* filename) 
  {
  AVIFileInit();  //初期化

//AVIファイルを開く
  AVIFileOpen(&PAvi,filename,OF_READ | OF_SHARE_DENY_NONE,NULL); 
  AVIFileGetStream(PAvi,&PStm,0,0); //AVIストリームを開く(1つのAVIに1つのストリームを想定)
  PFrm=AVIStreamGetFrameOpen(PStm,NULL);//GetFrameオブジェクト取得
  return 0;
    }

//指定したフレームにアクセスし、クリップボードに静止画を入れる。
int readAVI2CB(long frame) 
  {
  LPBITMAPINFOHEADER pbmih;  //VFWのAPIで取得した静止画(DIB)へのポインタを格納
  HGLOBAL hGlbl;  //GlobalAllocで確保したメモリへのポインタ
  long dibsize;  //DIBデータ容量を計算して格納
  void *PMem;  //GlobalLockしたときのメモリブロック先頭へのポインタ
  
  pbmih=(LPBITMAPINFOHEADER)AVIStreamGetFrame(PFrm,frame);//静止画取得
  if (pbmih->biClrUsed==0)
        switch (pbmih->biBitCount) {
            case  1:dibsize=(pbmih->biSize)+sizeof(RGBQUAD)*2+(pbmih->biSizeImage);
            case  4:dibsize=(pbmih->biSize)+sizeof(RGBQUAD)*16+(pbmih->biSizeImage);
      case  8:dibsize=(pbmih->biSize)+sizeof(RGBQUAD)*256+(pbmih->biSizeImage);
            case 24:dibsize=(pbmih->biSize)+(pbmih->biSizeImage);
            case 32:dibsize=(pbmih->biSize)+(pbmih->biSizeImage);
      }
  else  dibsize=(pbmih->biSize)+pbmih->biClrUsed*sizeof(RGBQUAD)+(pbmih->biSizeImage);

  hGlbl = GlobalAlloc(GHND ,dibsize); //メモリ確保
  PMem = GlobalLock(hGlbl); //確保したメモリをロックする
      CopyMemory(PMem, pbmih, dibsize); //確保・ロックしたメモリに画像データを書き込む
  GlobalUnlock(hGlbl); //ロックを解除

  OpenClipboard(NULL); //クリップボードオープン
  EmptyClipboard(); //クリップボードを空にする
  SetClipboardData(CF_DIB, hGlbl); //クリップボードにDIBデータを入れる
  CloseClipboard();//クリップボードを閉じる
  return 0;
    }

//開いたAVIを閉じる一連の動作
int closeAVI(void)  
  {
  AVIStreamGetFrameClose(PFrm); //フレームを閉じる
    AVIStreamRelease(PStm);  //ストリームを開放
    AVIFileRelease(PAvi);  //AVIファイルを開放
    AVIFileExit();      //VFW利用終了
   return 0;
    }


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加