
WindowsプログラミングでDirectshowを使って動画処理をしています。
最終的には、動画処理した結果をウィンドウに順に表示させていくプログラムを作りたいです。
そのため、まずは、下の手順のようなプログラムを現在作っています。
(1) 動画を1フレームごとに取り込む
(2) 情報をビットマップに書き出す
(3) ビットマップを読み込む
(4) ウィンドウに描画する
(5) (1)~(4)を繰り返す
プログラムはVisualStudio2005を使い、ウィンドウズアプリケーションで作成しています。
ウィンドウにビットマップが表示されてほしいのですが、何も表示されません。
2週間悩んでいますが、解決しません;;
以下にソースを貼らせていただきますので、アドバイスいただきたいです。
※ソースの量が多いので、WM_TIMER, WM_PAINTの部分を中心に載せています。
(その他の部分は、最初から書かれているソースからほぼ変更していないです)
なお、WM_TIMER部分については、文字数の関係から別アカウントから回答1に書かせていただきます。
-----------------------
<追加グローバル宣言>
int douga_flag=0; //メニューで動画処理を選ぶと1になります
IGraphBuilder *pigb = NULL; /* フィルタグラフ用 */
IMediaControl *pimc = NULL;
IMediaSeeking *pims = NULL;
IBaseFilter *pibf = NULL; /* サンプルグラブ用 */
ISampleGrabber *pisg = NULL;
IVideoWindow *pivw =NULL;
AM_MEDIA_TYPE amt;
HRESULT hr;
OAFilterState fs;
long n;
LONGLONG nn1, flame_number;
CImage1 gazou; /* ビットマップ画像のクラス */
// gazou.width(横サイズ), gazou.height(縦サイズ), gazou.bmmap_data(画像情報の入った配列)
/* 動画→lpBmpDataに情報がはいる */
typedef struct
{
HINSTANCE hi;
int x; // 表示開始位置
int y;
HWND hwnd; // 自分のウィンドウハンドル
BYTE *lpBmpData; // BMPのデータ部分
BITMAPINFOHEADER bih;
} IMG0;
IMG0 img00;
-----------------------
<WndProc(主に WM_PAINT のソース)>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
int id, ww, hh;
PAINTSTRUCT ps;
HBITMAP hBmp, hBmpOld;
BITMAP bmp_info;
HDC hdc, hdc_mem;
switch (message)
{
...省略...
case WM_TIMER:
//文字数の関係から別アカウントから回答1に書きます
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
hdc_mem = CreateCompatibleDC(hdc);
hBmp = LoadBitmap(hInst, TEXT("bitmap.bmp"));
GetObject(hBmp, (int)sizeof(BITMAP), &bmp_info);
ww = bmp_info.bmWidth;
hh = bmp_info.bmHeight;
hBmpOld = (HBITMAP)SelectObject(hdc_mem, hBmp);
BitBlt(hdc, 0, 0, ww, hh, hdc_mem, 0, 0, SRCCOPY);
SelectObject(hdc_mem, hBmpOld);
DeleteDC(hdc_mem);
DeleteObject( hBmp ); // ロードしたビットマップを削除する
EndPaint(hWnd, &ps);
break;
...省略...
}
A 回答 (1件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
質問者のTae_Springです。
WM_TIMERのソースを以下に貼らせていただきます。
なお、TIMERについてですが、既存のInitInstance関数でウィンドウの作成をした後、
SetTimer(hWnd, 100, 500, NULL); と設定しています。
(とりあえず500ミリセカンドで1回描画していくようにしています)
----------------------
<WM_TIMER のソース>
case WM_TIMER:
if(douga_flag==1)
{
/* (1)1回目だけおこなう処理 */
if(nn1==0)
{
gazou.open_bmmap("dummy.bmp"); //自作のビットマップ読み込み関数
// bitmap.bmpと同じ規格のdummy.bmpを読み込むことでビットマップ情報を先に取得しておく
// これにより、gazou.widthに横、gazou.heightに縦のサイズがはいり、
// gazou.bmmap_dataという動画処理用の配列を取得する
// COMの準備 + FilterGraph,GrabberFilter等の設定
<ソース省略>
// 再生するファイルを指定
hr = pigb -> RenderFile(TEXT("MOVIE.avi"), NULL );
// ビットマップ情報の取得
pisg -> GetConnectedMediaType( &amt );
// ビデオヘッダーには、ビットマップ情報が含まれる。
n = amt.lSampleSize;
img00.bih = ((VIDEOINFOHEADER*)amt.pbFormat) -> bmiHeader;
img00.lpBmpData = (BYTE *)malloc( amt.lSampleSize );
// シークをフレーム単位で行うよう設定
hr = pims -> SetTimeFormat( &(TIME_FORMAT_FRAME) ) ;
pims -> GetDuration(&flame_number);
// グラブ開始
pisg -> SetBufferSamples(TRUE);
}
/* (2)動画抽出 or 動画の最後に行う処理 */
if( nn1 <= flame_number){
// 動画情報を抽出する部分
pims -> SetPositions( &nn1, AM_SEEKING_AbsolutePositioning,
&nn1, AM_SEEKING_AbsolutePositioning );// シーク
pimc -> StopWhenReady();// シークしてレンダリング
pimc -> GetState( INFINITE, & fs);// レンダリング完了を待つ
pisg -> GetCurrentBuffer( &n, (long*)img00.lpBmpData );// グラブ
InvalidateRect( hWnd, NULL, FALSE); // 表示
nn1++;
// lpBmpDataの値を、ビットマップ表示用配列にコピー
for(int j=0; j<gazou.height; j++){
for(int i=0; i<gazou.width; i++){
gazou.bmmap_data[(j*gazou.width+i)*3] = int(img00.lpBmpData[(j*gazou.width+i)*3]);
gazou.bmmap_data[(j*gazou.width+i)*3+1] = int(img00.lpBmpData[(j*gazou.width+i)*3+1]);
gazou.bmmap_data[(j*gazou.width+i)*3+2] = int(img00.lpBmpData[(j*gazou.width+i)*3+2]);
}
}
// 自作のビットマップ書き込み関数→gazou.bmmap_dataの情報からbitmap.bmpを作成
gazou.out_bmmap("bitmap.bmp");
}else{
// FilterGraph他の開放
pigb -> Release();pimc -> Release();
pims -> Release();
pibf -> Release();pisg-> Release();
CoUninitialize();
nn1=0;
douga_flag=0; //←これで動画処理をぬける
}
}
break;
以上となります。
よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- Visual Basic(VBA) Vba LongPtrについて教えてください 2 2022/08/19 11:14
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- MySQL PHPとMySQLを使った掲示板の作り方 1 2022/06/02 13:00
- Perl 画像が表示でnull; this.src 1 2022/04/19 11:31
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- MySQL MySQLのテーブル作成で 自信がありません。 2 2022/08/28 05:35
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
WinAPI Directshow 動画
-
3のつく数と3の倍数を表示 C言語
-
| (or) を使った関数の引数の作...
-
C言語で%を使わない余りの出し方
-
10進法から2進法のCプロ
-
クリックされた地点が2点の線分...
-
「Aに対するBの割合」と「Aに対...
-
有効数字について 以前質問をし...
-
C言語での引数の省略方法
-
C言語を実行すると-infが出てき...
-
数学 確率変数Xは、X=2またはX...
-
DWORDの実際の型は何でしょうか
-
ある商品のロス率を5%見込み、...
-
プログラムでの数字につく”f”の...
-
複数桁10進数の*桁目だけを抽出...
-
*をユーザーが入力した数字の数...
-
エクセルの問題です。絶対値の...
-
16進数 加算 減算 C言語
-
2÷3などの余りについて
-
Win32APIでのエディットボック...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
おすすめ情報