ウインドウサイズの幅と高さを出力するには…

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ウィン

ウインドウサイズの幅と高さを出力するには…

#1

投稿記事 by ウィン » 16年前

初投稿です。何卒お願い致します。
はじめての動画ファイルプログラミングの第7章の7-1のサンプルを改造して、
フレームごとの色の特徴量を取れるプログラムを作成しています。省略するのも、良くないと思いますし、文字制限がありますので、区切って書き込みます。

// frame3.cpp DirectShowを使ったフレームの切り出しの応用
// ○list502.h、list502b.cppを合わせて、
//  コンソールアプリケーションで作成すること
// ○[プロジェクト][リンク]にstrmiids.lib を追加
// ○COMの操作はすべてHRESULTを返すが、プログラムを簡単にするため
// 最低限の吟味しか行っていない。
#include <windows.h>
#include <string.h>
#include <dshow.h>			// DirectShowのヘッダファイル
#include <qedit.h>			// SampleGrabber用
#include <conio.h>			// getch()用
#include <stdio.h>
#include "lis.h"

void main( void )
{
	// インターフェース用のポインタ
	// フィルタグラフ用
	IGraphBuilder *pigb  = NULL;
	IMediaControl *pimc  = NULL;
	IMediaSeeking *pims  = NULL;	 
	// サンプルグラバ用
	IBaseFilter    *pF   = NULL;
	ISampleGrabber *pGrab = NULL;	// これらは後で解放すること。

	IMG0	img00;					// 表示ウィンドウ用の構造体
	BYTE  *buffer;					// 外部バッファ
	AM_MEDIA_TYPE   amt;
	WCHAR filename[ MAX_PATH ];
	HRESULT hr;

	img00.hi = (HINSTANCE)GetWindowLong( HWND_DESKTOP, GWL_HINSTANCE );
	img00.x = 100; img00.y = 100;
    gr_reg();						// 表示用ウィンドウの登録

	CoInitialize(NULL);				// COMの準備

	// FilterGraphの初期化
	CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
					  IID_IGraphBuilder, (void **)&pigb);
	// フィルタグラフのインターフェースを得る
	pigb -> QueryInterface( IID_IMediaControl, (void **)&pimc );
	pigb -> QueryInterface( IID_IMediaSeeking, (void **)&pims );

	// グラバフィルタを作りフィルタグラフに追加
	CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, 
                      IID_IBaseFilter, (LPVOID *)&pF);
	pF -> QueryInterface( IID_ISampleGrabber, (void **)&pGrab );
	pigb -> AddFilter( pF, L"SamGra" );

	// グラバフィルタの挿入場所の特定のための設定
	ZeroMemory( &amt, sizeof(AM_MEDIA_TYPE) );
	amt.majortype  = MEDIATYPE_Video;
	amt.subtype    = MEDIASUBTYPE_RGB24;
	amt.formattype = FORMAT_VideoInfo; 
	pGrab -> SetMediaType(&amt);

	OPENFILENAME fname;
	static char fn[256];
	memset(&fname, 0, sizeof(OPENFILENAME));
	fname.lStructSize    = sizeof(OPENFILENAME);
	fname.lpstrFile      = fn;			// パス付きファイル名が格納されるアドレス	
	fname.nMaxFile       = sizeof(fn);
	fname.Flags          = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
	if( ! GetOpenFileName( &fname ) )	return ;

	// ファイル名の変換
	MultiByteToWideChar( CP_ACP, 0, fn, -1, filename, MAX_PATH );
	// 再生するファイルを指定、この時点で使用するフィルタが決まる
	hr = pigb -> RenderFile( filename, NULL );
	printf( "RenderFile hr %x\n", hr );
	if(hr != 0)		return;

	// ビットマップ情報の取得
	pGrab -> GetConnectedMediaType( &amt ); 
	// ビデオ ヘッダーへのポインタを獲得する。
	// ビデオ ヘッダーには、ビットマップ情報が含まれる。
	// ビットマップ情報を BITMAPINFO 構造体にコピーする。
	img00.bih = ((VIDEOINFOHEADER*)amt.pbFormat) ->bmiHeader;
	long n = amt.lSampleSize;
	buffer = (BYTE *)malloc( n );
	img00.lpBmpData=buffer;

	pims -> SetTimeFormat( &(TIME_FORMAT_FRAME) ) ;	
										// シークをフレーム単位で行うよう設定
~つづく

ウィン

Re:ウインドウサイズの幅と高さを出力するには…

#2

投稿記事 by ウィン » 16年前

続き
LONGLONG	nn;
	pims -> GetDuration( & nn );
	printf("フレーム数 %d\n",nn);
	// レンダリングとグラブ

	int n0, n1;
	printf( "開始フレーム?" );
	scanf( "%d", &n0 );
	printf( "終了フレーム?" );
	scanf( "%d", &n1 );
	gr_init( &img00 );					// グラフィックウィンドウを生成

	FILE * fp;
	char cbuf[300],cbuf2[300];
	int i;

	i=0;								// 結果ファイル名を編集
	while(fn != '.'){
		cbuf = fn;
		i++;
	}
	cbuf = 0;
	sprintf( cbuf2 , "%s.csv" , cbuf , nn );
	printf( "save [%s]\n",cbuf2 );
	fp = fopen( cbuf2,"w");


	int j,k;
	int ij;
	int cnt=0;
	int rr,gg,bb;
	int total_r=0,total_g=0,total_b=0;
	int total_r_ave,total_g_ave,total_b_ave;

	pGrab -> SetBufferSamples(TRUE);	// グラブ開始
	for( nn = n0; nn <= n1; nn=nn+15){
		// シーク
		pims -> SetPositions( &nn, AM_SEEKING_AbsolutePositioning,
					          &nn, AM_SEEKING_AbsolutePositioning );
	
		pimc->StopWhenReady();
												// シークしてレンダリング	
		printf( "run at %d\n", nn );
		
		OAFilterState fs;
		pimc->GetState( INFINITE, & fs);		// レンダリング完了を待つ
		pGrab -> GetCurrentBuffer( &n, (long *)buffer );
												// グラブ
		//for(j = 0; j< 100 *720 * 3;j++)			// 画面下部を無視
			//buffer[j]  = 0;
		InvalidateRect( img00.hwnd, NULL, FALSE);	// 表示 

									// 各特徴量の計算
		
		for(i = 0;i< 10 ;i=i++){
			for(j = 0;j< 31;j++){
				ij = i * 31 + j;
				bb = buffer[ ij * 3    ] ;		// b
				gg = buffer[ ij * 3 +1 ] ;		// g
				rr = buffer[ ij * 3 +2 ] ;		// r 
				k = rr * 0.299 + gg * 0.587 + bb * 0.114;
				if( k > 20 ){
					total_r=total_r+rr;
					total_g=total_g+gg;
					total_b=total_b+bb;
					
				
printf("%3d,%3d赤=%3d,緑=%3d,青=%3d\n",i,j,rr,gg,bb);
					cnt++; 
				}
			}
		}
		total_r_ave=total_r/cnt;
		total_g_ave=total_g/cnt;
		total_b_ave=total_b/cnt;
		printf("%3d %3d %3d\n",rr, gg, bb);
		printf("赤平均=%3d",total_r_ave);	//フレームごとの画面内赤平均値
		printf("緑平均=%3d",total_g_ave);	//フレームごとの画面内緑平均値
		printf("青平均=%3d",total_b_ave);	//フレームごとの画面内青平均値
		fprintf(fp,"%d , %d , %d \n", rr, gg, bb );
		

	}

	fclose( fp );
	printf("終了\n");
	getch();
	
	// FilterGraph他の開放
	pigb -> Release();	pimc -> Release();
	pims -> Release();	
	pF   -> Release();	pGrab-> Release();
	
	CoUninitialize();
	SendMessage( img00.hwnd, WM_CLOSE, 0, 0 );		// グラフィック画面の終了
	free( buffer );

	return ;

}

つづく

ウィン

Re:ウインドウサイズの幅と高さを出力するには…

#3

投稿記事 by ウィン » 16年前

続き
//  hojo.cpp
//
//         処理部分を書きやすくするため
//         コンソールアプリケーションの形態をとり
//       ウィンドウ関係の処理はスレッドに任せる
//		  そのためのスレッド側、ウィンドウ側リスト  	
#include "lis.h"

// グラフィック用のウィンドウクラスの登録
int gr_reg( void )							
{	
	WNDCLASSEX	wc;							// 新しくつくるウインドクラス

	memset( &wc, 0, sizeof(WNDCLASSEX) );
	wc.cbSize        = sizeof(WNDCLASSEX);	
	wc.lpfnWndProc   = grProc;				// このクラスの持つウインドプロシージャ
	wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
	wc.hInstance     = (HINSTANCE)GetWindowLong( HWND_DESKTOP, GWL_HINSTANCE ); 
	wc.lpszClassName = "GRC0";				// このクラスの名前
	wc.cbWndExtra    = 10;					// 関連する構造体のポインタ用のエリアを確保
	return RegisterClassEx( &wc );			// ウィンドクラスの登録
}

//	グラフィックウィンドウの生成,メッセージループ用スレッドの起動
void gr_init( IMG0 * pimg00)
{
	DWORD tid;

	pimg00 -> hwnd = NULL;
	CreateThread( NULL, 0,
				 (LPTHREAD_START_ROUTINE)th_Proc,
				 (void *)pimg00, 0, &tid );
											// メッセージループのスレッドを起動	
	while( !(pimg00 -> hwnd) );				// ウィンドウが表示されるのを待つ
}

// メッセージループのためのスレッド
DWORD th_Proc( void * pp)
{
	MSG msg;

	int sm0 = GetSystemMetrics( SM_CYCAPTION );
	int sm1 = GetSystemMetrics( SM_CXFIXEDFRAME );	// WS_OVRELAPPの場合、枠の太さは
	int sm2 = GetSystemMetrics( SM_CYFIXEDFRAME );	// SM_C?FIXEDFRAMEになる
	// 必ずスレッドの中でウィンドウを作る
	((IMG0 *)pp) -> hwnd = CreateWindow( "GRC0",	// クラスの名前
				"...",
				WS_OVERLAPPED | WS_VISIBLE,			// ウィンドウの属性
				((IMG0 *)pp) -> x, ((IMG0 *)pp) -> y,		// 表示位置
				((IMG0 *)pp) -> bih.biWidth  + sm1 * 2, 	// 描画サイズから大きさを計算
				((IMG0 *)pp) -> bih.biHeight + sm0 + sm2 * 2,
				HWND_DESKTOP,						// 親はディスクトップ
				NULL, ((IMG0 *)pp)->hi, NULL 	     );					
	SetWindowLong(((IMG0 *)pp) -> hwnd, 0, (LONG)pp);
	while( GetMessage( &msg, NULL, 0, 0 ) ){
		DispatchMessage( &msg );
	}

	return 0;
}

// ウィンドウプロシージャ,再描画のみを行う
LRESULT CALLBACK grProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
{
	IMG0 * pimg;				
	PAINTSTRUCT	ps;

	pimg = (IMG0 * )GetWindowLong( hwnd , 0 );		// 拡張ウィンドウメモリより
													// このウィンドウ用データへの
													// ポインタを取り出す
    switch (msg) {

	case WM_PAINT:									// ビットマップの描画
		BeginPaint( hwnd, &ps );
		SetDIBitsToDevice( ps.hdc, 0, 0,			// コピー先x,y座標
					pimg -> bih.biWidth,			// DIBの幅
					pimg -> bih.biHeight,			// DIBの高さ
					0, 0,							// DIBの座標 
					0,								// 走査線
					pimg -> bih.biHeight,			// 走査線数
					pimg -> lpBmpData,
					(BITMAPINFO *)&( pimg -> bih),	// BITMAPINFOにキャスト
					DIB_RGB_COLORS );
        EndPaint( hwnd, &ps );
		return 0;

	case WM_DESTROY:								// スレッドの
		PostQuitMessage( 0 );						// メッセージループを終了させる
		break;			

	default:
		return DefWindowProc( hwnd, msg, wp, lp );
	}
	return 0;
	
}

//
//	lis.h
//
#include <Windows.h>
#include <vfw.h>			// Video for Windows include file

// グラフィック用ウィンドウのデータをまとめた構造体
typedef struct{				
	HINSTANCE			hi;
	int					x;			// 表示開始位置
	int					y;
	HWND				hwnd;		// 自分のウィンドウハンドル
	BYTE				*lpBmpData; // BMPのデータ部分
	BITMAPINFOHEADER	bih;
} IMG0;

int gr_reg( void );
void gr_init(IMG0 *);
DWORD th_Proc( void *);
LRESULT CALLBACK grProc( HWND, UINT, WPARAM, LPARAM );

私が知りたいのは、for(i = 0;i< 10 ;i=i++){
for(j = 0;j< 31;j++){
の部分を変数を使って、for(i = 0;i< width ;i=i++){
for(j = 0;j< height;j++){
という風にしたいです。動画ファイル再生時のウインドウサイズを読み取って、変数に格納出来れば
どのようなファイルでも画面全体の特徴量を求められます。
ソースのビルドはしっかり出来ています。

動画関連の質問を尋ねている感じですが、実際はウインドウサイズを変数に入れてそれを利用したいというのが中身です。恥ずかしい話、ウインドウ関連のCはあまり知りません。
皆様どうか、ご教授お願い致します。

ウィン

Re:ウインドウサイズの幅と高さを出力するには…

#4

投稿記事 by ウィン » 16年前

忘れていました。
サンプルプログラムは
http://www.cqpub.co.jp/shoseki/mycomputer/pic019/
ここの7章の7-1から取りました。

Justy

Re:ウインドウサイズの幅と高さを出力するには…

#5

投稿記事 by Justy » 16年前

 本当にウインドウサイズでいいのですか?

 ウインドウサイズでいいのなら、CreateWindow()で与えている第6・7引数の値が
それぞれウインドウの幅と高さになります。
 それを記憶しておけばいいでしょう。


 でもウインドウサイズではなく、動画のサイズが欲しいので有れば、
img00変数のメンバ bih.biWidthと bih.biHeightにそれぞれ入っています。

ウィン

Re:ウインドウサイズの幅と高さを出力するには…

#6

投稿記事 by ウィン » 16年前

すっかり、間が空きましたが
その通りに設定したら、しっかり入りました。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る