由于GetBitmap
TVideoImage 的函数在调用 之后直接调用可能会传递空图像VideoStart
,因此可能需要创建TVideoImage
添加OnNewVideoFrame
事件以获取图像可用的信息。所以步骤是:
- 创建并启动
- 等待图像并采取它
- 自由的
由于问题是要求单次解决方案和线程或空闲循环在VideoStart
不起作用后,我将提供一个解决方案来封装上述步骤。
电话是:
procedure TMyForm.FormCreate(Sender: TObject);
begin
ReportMemoryLeaksOnShutDown := true;
end;
procedure TMyForm.ImgCallBack(BMP:TBitMap);
begin
Image1.Picture.Assign(BMP);
end;
procedure TMyForm.Button3Click(Sender: TObject);
begin
With TGrabClass.Create do GetImage(ImgCallBack);
end;
TGrabClass 的基本实现为:
unit u_GrabOnlyBitMap;
interface
uses
Classes,
Messages,
Windows,
Graphics,
VSample,
VFrames;
type
TImageCallBack=Procedure(bmp:TBitMap) of Object;
TGrabClass=Class
FReady:Boolean;
FVideo:TVideoImage;
FBitMap:TBitMap;
Handle:THandle;
FImageCallBack:TImageCallBack;
Procedure GetImage(cb:TImageCallBack);
Constructor Create;
Destructor Destroy;Override;
private
procedure NewVideoFrameEvent(Sender: TObject; Width, Height: integer;
DataPtr: pointer);
procedure WndMethod(var Msg: TMessage);
procedure Suicide;
End;
implementation
const
WM_MyKill=WM_user + 666;
// Called by asnc PostMessage with WM_MyKill to free
Procedure TGrabClass.WndMethod(var Msg: TMessage);
begin
if Msg.Msg = WM_MyKill then
begin
Msg.Result := -1;
Free;
end
else
Msg.Result := DefWindowProc(Handle, Msg.Msg, Msg.wParam, Msg.lParam);
end;
constructor TGrabClass.Create;
var
sl:TStringList;
begin
inherited;
Handle := AllocateHWnd(WndMethod);
sl:=TStringList.Create;
FVideo:=TVideoImage.Create;
FBitMap := TBitmap.Create;
FVideo.OnNewVideoFrame := NewVideoFrameEvent;
FVideo.GetListOfDevices(sl);
FReady := sl.Count > 0;
if FReady then FVideo.VideoStart(sl[0])
else Suicide;
sl.Free;
end;
destructor TGrabClass.Destroy;
begin
DeallocateHWnd(Handle);
FVideo.VideoStop;
FVideo.Free;
FBitMap.Free;
inherited;
end;
Procedure TGrabClass.Suicide;
begin
// No device found Callback with empty image and Postmessage for freeing
if Assigned(FImageCallBack) then FImageCallBack(FBitMap);
PostMessage(handle,WM_MyKill,0,0);
end;
Procedure TGrabClass.NewVideoFrameEvent(Sender : TObject; Width, Height: integer; DataPtr: pointer);
begin // we got a bitmap
FVideo.OnNewVideoFrame := Nil;
FVideo.GetBitmap(FBitMap);
if Assigned(FImageCallBack) then FImageCallBack(FBitMap);
PostMessage(handle,WM_MyKill,0,0);
end;
procedure TGrabClass.GetImage(cb: TImageCallBack);
begin
FImageCallBack := cb;
end;
end.