menu_bar

第 20 章 ビデオキャプチャをする
Last Modify 2007/12/25 20:01:48


ようやく 最後かなぁ と 思っていたりするのですが、実は ちょっと
別のこともやりたくなったので、ついでに、書くかもしれません。
--

まず、やっぱり function の 場所が違うので、lib の 作り直しから
始まります。

まず、w32api-1.2/lib/vfw32.def の 一番最後

capGetDriverDescriptionW@20
capGetDriverDescriptionA@20
capCreateCaptureWindowW@32
capCreateCaptureWindowA@32

の部分を、

;capGetDriverDescriptionW@20
;capGetDriverDescriptionA@20
;capCreateCaptureWindowW@32
;capCreateCaptureWindowA@32

の用に コメントアウトします。

そして、同じディレクトリにある avi.defに 
capGetDriverDescriptionW@20
capGetDriverDescriptionA@20
capCreateCaptureWindowW@32
capCreateCaptureWindowA@32
を付加して、make 

できあがった、libvfw32.a libavi.a を /usr/local/mingw32/i386-mingw/lib
に コピーします。

以下の プログラムをコンパイルするときは、libavi を リンクするのを
忘れないで下さい。

また、今回 キャプチャデバイスを 24bpp と 思い込んで 書いています。(^^;;;
まぁ 一応 動くということを 確認したかっただけですから、、、
ちゃんと 画像を 動かせるようにするには、一部 変更しないと いけませんよっ。
(まぁ いろんな WEB サイトがあるので 自分で頑張ってぇぇ)

----
ヘッダファイル

#define IDM_OPEN  100
#define IDM_END   200
#define IDM_STOP  300
#define IDM_FORMAT 400
#define IDM_SOURCE 500

----
リソースファイル

#include "sample020.h"
// sample020.rc

// ICON
SAMPLE_ICON ICON  DISCARDABLE "Sample.ico"

// Menu
SAMPLE_MENU MENU DISCARDABLE
BEGIN
  POPUP "FILE(&F)"
  BEGIN
    MENUITEM "OPEN(&O)",		IDM_OPEN
    MENUITEM "STOP(&S)",		IDM_STOP
    MENUITEM SEPARATOR
    MENUITEM "FORMAT(&F)",               IDM_FORMAT
    MENUITEM "SOURCE",                   IDM_SOURCE
    MENUITEM SEPARATOR
    MENUITEM "QUIT(&Q)",		IDM_END
  END
END

ーーーーーーーーーーーーー
ソース

#include "windows.h"
#include "stdlib.h"
#include "stdio.h"
#include "sample020.h"

#include "vfw.h"
#include "mmsystem.h"


// sample020.cpp

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInstance_Current;

HWND hWndVideo;
void InitVideo(HWND);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst,
		   LPSTR lpszCmdLine, int nCmdShow)
{
  HWND hWnd; // ウィンドウクラス
  MSG message;
  WNDCLASS app;
  char ClassName[] = "Window_Class_Name";

  RECT rect;
  memset(&rect,0,sizeof(RECT));  
  AdjustWindowRect(&rect,WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION
		   | WS_THICKFRAME, TRUE);
  
  hInstance_Current = hInstance;

  if(!hPreInst)
    {
      app.style       = CS_HREDRAW | CS_VREDRAW; // ウィンドウの属性
      app.lpfnWndProc = WndProc; // ウィンドウプロシージャーの登録
      app.cbClsExtra  = 0; // WNDCLASS の メモリ追加領域 
      app.cbWndExtra  = 0; // インスタンスの メモリ追加領域
      app.hInstance   = hInstance; // インスタンスの登録
      app.hIcon       = LoadIcon(hInstance, "SAMPLE_ICON"); 
                                     // ウィンドウアイコン
      app.hCursor     = LoadCursor(NULL,IDC_ARROW); // ウィンドウカーソル
      app.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);  // 背景
      app.lpszMenuName  = "SAMPLE_MENU"; // メニューの名前登録
      app.lpszClassName = ClassName; // クラス名 他のウィンドウとの重複不可

      if(!RegisterClass(&app)) // ウィンドウクラスの登録
	return FALSE; // 失敗なら終了
    }

  hWnd= CreateWindow(ClassName, // クラス名
		     "Capture", // ウィンドウの名前
		     WS_OVERLAPPEDWINDOW, // ウィンドウの スタイル
		     100, // x座標
		     100, // y座標
		     rect.right - rect.left, // ウィンドウの 横幅
		     rect.bottom - rect.top, // ウィンドウの 高さ
		     NULL, // 親ウィンドウのハンドル (自分が親なら NULL)
		     NULL, // メニューのハンドル、
		     hInstance, // インスタンスハンドル
		     NULL); // ウィンドウ作成データ (後の章で使います)

  

  ShowWindow(hWnd,nCmdShow);  // 描画
  UpdateWindow(hWnd);



  while(GetMessage(&message,NULL,0,0))
    {
      TranslateMessage(&message);
      DispatchMessage(&message);
    }
  
  return message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
			 WPARAM wParam, LPARAM lParam)
{

// イベント処理
  switch(message)
    {
    case WM_CREATE:
      InitVideo(hWnd);
      PostMessage(hWnd,WM_SIZE,0,0);
      break;

    case WM_MOVE:
    case WM_SIZE:
      RECT rect;
      CAPSTATUS CapStatus;
      char str[256];


      capGetStatus(hWndVideo, &CapStatus,sizeof(CAPSTATUS));

      /*      
      HMENU hMenu;
      hMenu = GetMenu(hWnd);
      GetMenuItemRect(hWndVideo,hMenu,0,&rect);

      SetWindowPos(hWnd,NULL,0,0,
		   CapStatus.uiImageWidth + 6,
		   CapStatus.uiImageHeight + 25 + rect.bottom - rect.top,
		   SWP_NOZORDER | SWP_NOMOVE);

      SetWindowPos(hWndVideo,NULL,0,0,CapStatus.uiImageWidth,
		   CapStatus.uiImageHeight,SWP_NOZORDER|SWP_NOMOVE);
		   */


      memset(&rect,0,sizeof(RECT));
      rect.top = 100;
      rect.left = 100;

      rect.right = CapStatus.uiImageWidth+100;
      rect.bottom = CapStatus.uiImageHeight+100;

      AdjustWindowRect(&rect,WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION
		       | WS_THICKFRAME, TRUE);

      SetWindowPos(hWnd, HWND_TOP,rect.left,rect.top,
		   rect.right-rect.left,
		   rect.bottom-rect.top,SWP_SHOWWINDOW);

      MoveWindow(hWndVideo,0,0,
		 CapStatus.uiImageWidth,
		 CapStatus.uiImageHeight,FALSE);

      break;


    case WM_DESTROY:
      
      PostQuitMessage(0);
      break;


    case WM_COMMAND:
      switch(LOWORD(wParam))
	{
	case IDM_END:
	  SendMessage(hWnd, WM_CLOSE, 0,0);
	  break;

	case IDM_OPEN:


	  break;

	case IDM_FORMAT:
	  capDlgVideoFormat(hWndVideo);
	  break;

	case IDM_SOURCE:
	  capDlgVideoSource(hWndVideo);
	  break;
	  
	case IDM_STOP:
	  DestroyWindow(hWndVideo);

	  break;

	}
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
    }
  
  return 0;
}



void InitVideo(HWND hWnd)
{
  char DeviceName[80];
  char DeviceVersion[80];

  DWORD FormatSize;
  BITMAPINFOHEADER Format;
  
  char str[256];  

  hWndVideo = capCreateCaptureWindow("Capture",WS_CHILD | WS_VISIBLE,
  				     0,0,320,240,hWnd,0);
  
  capGetDriverDescription(0,  //device number
			  DeviceName,
			  sizeof(DeviceName),
			  DeviceVersion,
			  sizeof(DeviceVersion));
  
  MessageBox(hWnd,DeviceName,DeviceVersion,MB_OK);

  capDriverConnect(hWndVideo,0);

  FormatSize = capGetVideoFormatSize(hWndVideo);
  
  if(!capGetVideoFormat(hWndVideo, &Format, FormatSize))
    {
      DestroyWindow(hWndVideo);
      return;
    }


  CAPTUREPARMS CapParam;
  
  capCaptureGetSetup(hWndVideo,&CapParam,sizeof(CAPTUREPARMS));
  CapParam.dwRequestMicroSecPerFrame = (DWORD)(1000000 / 30);
  
  capPreviewRate(hWndVideo,66);
  capPreview(hWndVideo,TRUE);
  capOverlay(hWndVideo,TRUE);
  capCaptureSetSetup(hWndVideo,&CapParam,sizeof(CAPTUREPARMS));
  
  return;
}


もし、16bps の カメラを使うと 色が 変になるので、overray 外して call back 関数を 埋め込んで 適当に bitblt か 何かの関数で surface に 書き込んで下さい。(^^)v
目次へ


単純リンク・相互リンク 大歓迎です
ご意見、ご感想は、umeda@tele.ucl.ac.beまで
履歴書など TEL +32 10 47 80 74 (オフィス)