상세 컨텐츠

본문 제목

웹캠(WebCam) 다루기

프로젝트/Ah!FreeCa

by ryujt 2010. 11. 2. 17:12

본문

화상 강의 관련 프로젝트를 자주 하다보니, 웹캠을 다뤄야할 일이 많습니다.  DSPack을 이용해서 사용하다가 가끔씩 오동작을 하는 캠이 있어서, 이리 저리 수정하긴 했지만, 불안하기도 하고 해서, 쉽게 VideoGrabber를 이용하기로 했습니다.  상용 컴포넌트이고 다소 무거운(프로그램 사이즈가 커집니다) 것이 불만이긴 하지만, 잘 돌아갑니다.

이번 포스트에서는 VideoGrabber를 이용하여, 캠에서 Bitmap 데이터를 스냅 샷으로 잡아오기 위한 간단한 클래스를 설명하겠습니다.

소스는 아래 주소를 참고하시기 바랍니다.
Web Site : http://dev.naver.com/projects/ryulib4delphi
Subversion :  https://dev.naver.com/svn/ryulib4delphi
  - Unit : WebCam.pas
  - 예제 : Samples\WebCam

우선 웹캠을 쉽게 다루기 위하여 만든 TWebCamCtrl의 인터페이스를 살펴보도록 하겠습니다.

[그림 1] TWebCamCtrl의 인터페이스

[그림 1]에서 보는 것처럼 간단한 인터페이스를 갖추고 있습니다.  각각의 설명은 아래와 같습니다.
  • Method
    • procedure Start;
      • 웹캠을 작동 시킵니다.  성공하면, 미리보기가 보이기 시작합니다.
    • procedure Stop;
      • 웹캠 작동을 중지 시킵니다.
    • procedure Capture;
      • 현재의 화면을 Bitmap으로 캡쳐합니다.  성공하면, OnCaputred 이벤트가 발생합니다.
    • function SnapShot(ABitmap:TBitmap):boolean;
      • 스냅 샷을 얻어서 ABitmap에 해당 데이터를 옮겨 줍니다.  성공하면 리턴 값이 불린이 됩니다.
      • 캡쳐 자체는 성공했으나, 메소드의 실행 결과가 false 일 수도 있습니다.  비동기로 동작하기 때문에, 스냅 샷의 경우에는 반복적으로 요청해서 사용합니다.
      • Capture 메소드와 같이 OnCaputred 이벤트가 발생합니다.
  • Property
    • property Active : boolean;  // Read Only
      • 카메라가 동작 중인 지 여부를 알려줍니다.
    • property DeviceNo : Integer;
      • 웹캠이 여러 대 설치가 되어 있다면, DeviceNo를 변경하는 것으로 웹캠을 선별하여 동작 시킬 수 있습니다.
    • property Resolution : Integer;
      • 지원되는 해상도 중 하나를 선택할 수가 있습니다.
    • property DeviceList : TStringList;  // Read Only
      • 설치된 웹캠 목록을 알려줍니다.
    • property ResolutionList : TStringList;  // Read Only
      • 사용 가능한 해상도 목록을 알려줍니다.
  • Event
    • property OnCaptured : TCapturedEvent;
      • 스냅 샷을 요구하면, TBitmap 클래스를 인자로 해서 OnCaptured 이벤트가 발생합니다.
예제를 통해서 실제 사용 방법을 살펴보면 다음과 같습니다.  소스가 간단하기 때문에 따로 설명이 필요 없을 것으로 보입니다.

unit main;

interface

uses
  WebCam,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TfmMain = class(TForm)
    btSnapShot: TButton;
    btStart: TButton;
    btStop: TButton;
    plCam: TPanel;
    Image: TImage;
    cbDeviceList: TComboBox;
    cbResolutionList: TComboBox;
    Timer: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btStartClick(Sender: TObject);
    procedure btStopClick(Sender: TObject);
    procedure cbResolutionListChange(Sender: TObject);
    procedure cbDeviceListChange(Sender: TObject);
    procedure TimerTimer(Sender: TObject);
  private
    FWebCam : TWebCamCtrl;
    procedure on_Captured(Sender:TObject; const ABitmap:TBitmap);
  public
  end;

var
  fmMain: TfmMain;

implementation

{$R *.dfm}

procedure TfmMain.btStartClick(Sender: TObject);
begin
  FWebCam.Start;

  cbResolutionList.Items.Text := FWebCam.ResolutionList.Text;
  cbResolutionList.ItemIndex := 0;
end;

procedure TfmMain.btStopClick(Sender: TObject);
begin
  FWebCam.Stop;
end;

procedure TfmMain.cbDeviceListChange(Sender: TObject);
begin
  if cbDeviceList.ItemIndex > -1 then
    FWebCam.DeviceNo := cbDeviceList.ItemIndex;
end;

procedure TfmMain.cbResolutionListChange(Sender: TObject);
begin
  if cbResolutionList.ItemIndex > -1 then
    FWebCam.Resolution := cbResolutionList.ItemIndex;
end;

procedure TfmMain.FormCreate(Sender: TObject);
begin
  FWebCam := TWebCamCtrl.Create(Self);
  FWebCam.Align  := alClient;
  FWebCam.Parent := plCam;
  FWebCam.OnCaptured := on_Captured;

  cbDeviceList.Items.Text := FWebCam.DeviceList.Text;
  cbDeviceList.ItemIndex := 0;
end;

procedure TfmMain.FormDestroy(Sender: TObject);
begin
  FWebCam.Free;
end;

procedure TfmMain.on_Captured(Sender: TObject; const ABitmap: TBitmap);
begin
  Image.Picture.Bitmap.Assign(ABitmap);
end;

procedure TfmMain.TimerTimer(Sender: TObject);
begin
  Timer.Enabled := false;
  try
    FWebCam.Capture;
//    if FWebCam.SnapShot(Image.Picture.Bitmap) then ; // do Something
  finally
    Timer.Enabled := true;
  end;
end;

end.

화면 구성은 아래와 같이 설정하였습니다.

[그림 2] 예제의 화면 설정



관련글 더보기