Video For WindowsのLPVOID AVIStreamGetFrame(pget, lPos)で取得した
フレームの画像をDIB形式でクリップボードに送りたいのですが、その方法
をご教授ください。
AVIStreamGetFrameでは、BITMAPINFOHEADERへのポインタが戻ってくる
ようですが、WindowsDIBファイルでいうBITMAPFILEHEADERを除いたあとの
部分がメモリに格納されているのでしょうか?(パックDIBて何?)
クリップボードへの転送にはSetClipboardData(uFormat, hMem)が使えそ
うなのですが、第2引数に何を入れたらよいのかわからないのです。
よろしくお願いします。
投稿者です。
以下のサイトの情報を参考にして、目的のプログラムを作って
みました。なんとか目的を達しているようにも思いますが、
いまいち自信がありません。アドバイスいただければ幸いです。
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;
}
ツイート | ![]() |