今回はVFW(Video For Windows)によるウェブカメラキャプチャを行ってみます
#include <tchar.h> #include <windows.h> #include <vfw.h> #pragma comment(lib,"vfw32.lib") // ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if(msg == WM_DESTROY) PostQuitMessage(0); return (DefWindowProc(hWnd, msg, wParam, lParam)); } // キャプチャーコールバック関数 LRESULT CALLBACK capVideoStreamCallback(HWND hWnd,LPVIDEOHDR lpVHdr){ // エンターキーでスナップショット if(GetAsyncKeyState(VK_RETURN)) capFileSaveDIB(hWnd,_T("capture.bmp")); // キャプチャー画像ピクセルデータ //lpVHdr->lpData return TRUE; } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) { const TCHAR* WC_BASIC = _T("Basic"); // ウィンドウクラス名 /********************************************/ /* ウィンドウクラスの定義と登録 */ /********************************************/ // シンプルウィンドウクラス設定 WNDCLASSEX wcex ={sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, WndProc, 0,0,hInstance, (HICON)LoadImage(NULL,MAKEINTRESOURCE(IDI_APPLICATION),IMAGE_ICON,0,0,LR_DEFAULTSIZE | LR_SHARED), (HCURSOR)LoadImage(NULL,MAKEINTRESOURCE(IDC_ARROW),IMAGE_CURSOR,0,0,LR_DEFAULTSIZE | LR_SHARED), (HBRUSH)GetStockObject(WHITE_BRUSH), NULL, WC_BASIC , NULL}; // シンプルウィンドウクラス登録 RegisterClassEx(&wcex); /********************************************/ /* ウィンドウの作成 */ /********************************************/ HWND hWnd = CreateWindowEx( 0, //拡張ウィンドウスタイル WC_BASIC, //ウィンドウクラス名 _T("タイトル"), //タイトルバーにこの名前が表示されます WS_OVERLAPPEDWINDOW | WS_VISIBLE, //ウィンドウスタイル CW_USEDEFAULT, //X座標 CW_USEDEFAULT, //Y座標 640, //幅 480, //高さ NULL, //親ウィンドウのハンドル、親を作るときはNULL NULL, //メニューハンドルorリソースID hInstance, //インスタンスハンドル NULL); // キャプチャーウィンドウ RECT rect; GetClientRect(hWnd,&rect); HWND hWndCap = capCreateCaptureWindow( _T("Capture Window"), // キャプチャウィンドウの名前 WS_CHILD | WS_VISIBLE, // ウィンドウスタイル 0, 0, // 表示位置 rect.right - rect.left, rect.bottom - rect.top, // ウィンドウサイズ hWnd, // 親のハンドル NULL); capDriverConnect( hWndCap, 0 ); // チャンネル1に接続 capPreviewRate( hWndCap, 1 ); // プレビューレートの設定 数字が小さいほど速くキャプチャーします。 capPreview( hWndCap, TRUE ); // プレビューモード // ビデオフォーマット取得 BITMAPINFO bmpinfo; capGetVideoFormat(hWndCap,&bmpinfo,sizeof(BITMAPINFO)); // キャプチャーするたびに呼ばれる関数登録 capSetCallbackOnFrame(hWndCap,capVideoStreamCallback); MSG msg={0}; while (GetMessage(&msg,0,0,0)) DispatchMessage(&msg); capDriverDisconnect (hWndCap); return 0; } VFWを使うには以下のヘッダーとライブラリが必要です #include <vfw.h> #pragma comment(lib,"vfw32.lib") まず、キャプチャーウィンドウをcapCreateCaptureWindow関数で作成する必要があります // キャプチャーウィンドウ RECT rect; GetClientRect(hWnd,&rect); HWND hWndCap = capCreateCaptureWindow( _T("Capture Window"), // キャプチャウィンドウの名前 WS_CHILD | WS_VISIBLE, // ウィンドウスタイル 0, 0, // 表示位置 rect.right - rect.left, rect.bottom - rect.top, // ウィンドウサイズ hWnd, // 親のハンドル NULL); ウィンドウ作成後 capDriverConnect( hWndCap, 0 ); // チャンネル1に接続 capPreviewRate( hWndCap, 1 ); // プレビューレートの設定 数字が小さいほど速くキャプチャーします。 capPreview( hWndCap, TRUE ); // プレビューモード キャプチャーウィンドウを破棄するときにはチャンネルの接続を切ってください capDriverDisconnect (hWndCap); 各フレームごとにキャプチャー画像のピクセル情報を取得したい場合は // キャプチャーコールバック関数 LRESULT CALLBACK capVideoStreamCallback(HWND hWnd,LPVIDEOHDR lpVHdr){ // エンターキーでスナップショット if(GetAsyncKeyState(VK_RETURN)) capFileSaveDIB(hWnd,_T("capture.bmp")); // キャプチャー画像ピクセルデータ //lpVHdr->lpData return TRUE; } キャプチャーコールバック関数はcapSetCallbackOnFrameマクロで登録することで // キャプチャーするたびに呼ばれる関数登録 capSetCallbackOnFrame(hWndCap,capVideoStreamCallback); キャプチャー画像を保存するにはcapFileSaveDIBマクロを使います capFileSaveDIB(hWnd,_T("capture.bmp")); コールバック関数で書いてはいますが、キャプチャーが成功していればコールバック関数以外でも使えます 今回、処理はしていませんが動画像処理するときには // キャプチャー画像ピクセルデータ //lpVHdr->lpData 全ソースコードは下から
|