Delphi对摄像头的控制很简单,在System,windows和messages三个单元内已定义了所有的底层消息函数,我们只需要合理的调用它们就行了。我把摄像头的有关操作做成一个控件,这样就可以拖动窗体上直接使用了。
- {************************************
- * Camera Control for Delphi7 *
- * Made by Rarnu *
- * Credit 2006.08.27 *
- * http://rarnu.ik8.com *
- ************************************}
- unit RaCameraEye;
- interface
- uses
- SysUtils, Classes, Controls, Windows, Messages;
- {事件声明}
- type
- {开始摄像事件}
- TOnStart = procedure(Sender: TObject) of object;
- {停止摄像事件}
- TOnStop = procedure(Sender: TObject) of object;
- {开始录像事件}
- TOnStartRecord = procedure(Sender: TObject) of object;
- {停止录像事件}
- TOnStopRecord = procedure(Sender: TObject) of object;
- type
- TRaCameraEye = class(TComponent)
- private
- {图像显示容器}
- fDisplay: TWinControl;
- {事件关联变量}
- fOnStart: TOnStart;
- fOnStartRecord: TOnStartRecord;
- fOnStop: TOnStop;
- fOnStopRecord: TOnStopRecord;
- protected
- public
- {构造&析构,由TComponent类覆盖而来}
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- {开始摄像}
- procedure Start;
- {停止摄像}
- procedure Stop;
- {截图并保存到bmp}
- procedure SaveToBmp(FileName: string);
- {录制AVI}
- procedure RecordToAVI(FileName: string);
- {停止录制}
- procedure StopRecord;
- published
- property Display: TWinControl read fDisplay write fDisplay;
- property OnStart: TOnStart read fOnStart write fOnStart;
- property OnStop: TOnStop read fOnStop write fOnStop;
- property OnStartRecord: TOnStartRecord read fOnStartRecord write fOnStartRecord;
- property OnStopRecord: TOnStopRecord read fOnStopRecord write fOnStopRecord;
- end;
- {消息常量声明}
- const
- WM_CAP_START = WM_USER;
- WM_CAP_STOP = WM_CAP_START + 68;
- WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
- WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
- WM_CAP_SAVEDIB = WM_CAP_START + 25;
- WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
- WM_CAP_SEQUENCE = WM_CAP_START + 62;
- WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;
- WM_CAP_SEQUENCE_NOFILE = WM_CAP_START + 63;
- WM_CAP_SET_OVERLAY = WM_CAP_START + 51;
- WM_CAP_SET_PREVIEW = WM_CAP_START + 50;
- WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START + 6;
- WM_CAP_SET_CALLBACK_ERROR = WM_CAP_START + 2;
- WM_CAP_SET_CALLBACK_STATUSA = WM_CAP_START + 3;
- WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START + 5;
- WM_CAP_SET_SCALE = WM_CAP_START + 53;
- WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52;
- {声明动态函数,此函数从DLL中调入,动态判断是否可用}
- type
- TFunCap = function(
- lpszWindowName: PCHAR;
- dwStyle: longint;
- x: integer;
- y: integer;
- nWidth: integer;
- nHeight: integer;
- ParentWin: HWND;
- nId: integer): HWND; stdcall;
- {全局变量声明}
- var
- hWndC: THandle;
- FunCap: TFunCap;
- DllHandle: THandle;
- procedure Register;
- implementation
- procedure Register;
- begin
- RegisterComponents('Rarnu Components', [TRaCameraEye]);
- end;
- { TRaCameraEye }
- constructor TRaCameraEye.Create(AOwner: TComponent);
- var
- FPointer: Pointer;{函数指针}
- begin
- inherited Create(AOwner);
- fDisplay := nil;
- {通过DLL调入,如果DLL不存在,表示没有驱动}
- DllHandle := LoadLibrary('AVICAP32.DLL');
- if DllHandle <= 0 then
- begin
- MessageBox(TWinControl(Owner).Handle, '未安装摄像头驱动或驱动程序无效,不能使用此控件!', '出错', MB_OK or MB_ICONERROR);
- Destroy;{释放控件}
- Exit;
- end;
- {函数指针指向指定API}
- FPointer := GetProcAddress(DllHandle, 'capCreateCaptureWindowA');
- {恢复函数指针到实体函数}
- FunCap := TFunCap(FPointer);
- end;
- destructor TRaCameraEye.Destroy;
- begin
- StopRecord;
- Stop;
- fDisplay := nil;
- {如果已加载DLL,则释放掉}
- if DllHandle > 0 then
- FreeLibrary(DllHandle);
- inherited Destroy;
- end;
- procedure TRaCameraEye.RecordToAVI(FileName: string);
- begin
- if hWndC <> 0 then
- begin
- SendMessage(hWndC, WM_CAP_FILE_SET_CAPTURE_FILEA, 0, longint(PCHAR(FileName)));
- SendMessage(hWndC, WM_CAP_SEQUENCE, 0, 0);
- if Assigned(OnStartRecord) then
- OnStartRecord(Self);
- end;
- end;
- procedure TRaCameraEye.SaveToBmp(FileName: string);
- begin
- if hWndC <> 0 then
- SendMessage(hWndC, WM_CAP_SAVEDIB, 0, longint(PCHAR(FileName)));
- end;
- procedure TRaCameraEye.Start;
- var
- OHandle: THandle;
- begin
- if fDisplay = nil then Exit;
- OHandle := TWinControl(Owner).Handle;
- {动态函数控制摄像头}
- hWndC := FunCap(
- 'My Own Capture Window',
- WS_CHILD or WS_VISIBLE,
- {规定显示范围}
- fDisplay.Left, fDisplay.Top, fDisplay.Width, fDisplay.Height,
- OHandle, 0);
- if hWndC <> 0 then
- begin
- {发送指令}
- SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);
- SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
- SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0);
- SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
- SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0);
- SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0);
- SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0);
- SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0);
- end;
- if Assigned(OnStart) then
- OnStart(Self);
- end;
- procedure TRaCameraEye.Stop;
- begin
- if hWndC <> 0 then
- begin
- SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
- hWndC := 0;
- if Assigned(OnStop) then
- OnStop(Self);
- end;
- end;
- procedure TRaCameraEye.StopRecord;
- begin
- if hWndC <> 0 then
- begin
- SendMessage(hWndC, WM_CAP_STOP, 0, 0);
- if Assigned(OnStopRecord) then
- OnStopRecord(Self);
- end;
- end;
- end.