Delphi做得摄像头视频采集程序,为什么最小化后就没法采集了? ( 积分: 200 )

  • 主题发起人 主题发起人 薄荷
  • 开始时间 开始时间

薄荷

Unregistered / Unconfirmed
GUEST, unregistred user!
我用vfw做了一个视频采集的程序,使用摄像头进行采集,平时都正常,但是一旦最小化后,就停止采集了,我是使用定时器,定时保存到文件里,timer正常触发,就是图片始终是最小化前的最后一张图片。
下面是我程序里三个相关的函数。
/// <summary>
/// 连接摄像头
/// </summary>
/// <param name=&quot;AHandle&quot;>程序的局部 </param>
/// <param name=&quot;CapPos&quot;>frmCapture弹出的位置 </param>
/// <returns> </returns>
function ConnectVideo(AHandle: THandle;
CapPos: TPoint;
VideoWin: TWinControl): boolean;
stdcall;
var
dwSize:Integer;
setBmp : BITMAPINFO;
begin

result := false;
try
if VideoWin<>nil then
vWin := VideoWin
else
begin

FrmCapture := TfrmCapture.Create(nil);
//创建,在frmCapture的onclose事件里释放。
FrmCapture.Left := CapPos.X;
//self.Left+self.Width;
FrmCapture.Top := CapPos.Y;
//self.Top;
FrmCapture.Show;
vWin := VideoWin;
end;

CapWnd:=capCreateCaptureWindow('',
WS_CHILD or WS_VISIBLE,0,0,vWin.width,vWin.height,
vWin.Handle,0);
//FrmCapture.PnlVideo 就是要显示的视频窗口的;可以是form ,panel等
//AviPanel.width就是显示的宽度,AviPanel.height显示的高度;
if(capDriverConnect(CapWnd,0)) then

begin

//capOverlay(m_hCapWnd,true);
//普通的摄像头不能用overlay的方式
capPreviewRate(CapWnd,30);
//设置帧率为30
capPreview(CapWnd,true);
// preview方式显示
dwSize:=capGetVideoFormatSize(CapWnd);
capGetVideoFormat(CapWnd,@setBmp, dwSize);
setBmp.bmiHeader.biWidth:=vWin.Width;
//设置捕捉图片的大小了 宽度
setBmp.bmiHeader.biHeight:=vWin.Height;
//设置捕捉图片的大小了 高度
capSetVideoFormat(CapWnd,@setBmp,dwSize);
Result := true;
end
else
begin

if frmCapture<>nil then
//释放
begin

frmCapture.Close;
FreeAndNil(frmCapture);
end;

end;

except
end;

end;

/// <summary>
/// 断开和摄像头的连接
/// </summary>
/// <returns> </returns>
function DisconnectVideo(): boolean;
stdcall;
begin

Result := false;
vWin := nil;
if CapWnd=0 then
exit;
capDriverDisconnect(CapWnd);// vfw里面的标准函数
if Assigned(frmCapture) then

begin

frmCapture.Close;
FreeAndNil(frmCapture);
Result := true;
end;

end;

/// <summary>
/// 抓图,然后把图赋值给Photo,
/// </summary>
/// <param name=&quot;Photo&quot;>抓取的图片 </param>
/// <returns> </returns>
function CaptureFrame(var Photo: TBitmap): boolean;
stdcall;
begin

Result := false;
if CapWnd=0 then
exit;
try
if not capEditCopy(CapWnd) then
exit;
//把图像拷到剪贴板
if not Assigned(Photo) then
exit;
Photo.LoadFromClipboardFormat(CF_BITMAP,Clipboard.GetAsHandle(CF_BITMAP), 0);
Result := true;
except
result := false;
end;

end;
 
我用vfw做了一个视频采集的程序,使用摄像头进行采集,平时都正常,但是一旦最小化后,就停止采集了,我是使用定时器,定时保存到文件里,timer正常触发,就是图片始终是最小化前的最后一张图片。
下面是我程序里三个相关的函数。
/// <summary>
/// 连接摄像头
/// </summary>
/// <param name=&quot;AHandle&quot;>程序的局部 </param>
/// <param name=&quot;CapPos&quot;>frmCapture弹出的位置 </param>
/// <returns> </returns>
function ConnectVideo(AHandle: THandle;
CapPos: TPoint;
VideoWin: TWinControl): boolean;
stdcall;
var
dwSize:Integer;
setBmp : BITMAPINFO;
begin

result := false;
try
if VideoWin<>nil then
vWin := VideoWin
else
begin

FrmCapture := TfrmCapture.Create(nil);
//创建,在frmCapture的onclose事件里释放。
FrmCapture.Left := CapPos.X;
//self.Left+self.Width;
FrmCapture.Top := CapPos.Y;
//self.Top;
FrmCapture.Show;
vWin := VideoWin;
end;

CapWnd:=capCreateCaptureWindow('',
WS_CHILD or WS_VISIBLE,0,0,vWin.width,vWin.height,
vWin.Handle,0);
//FrmCapture.PnlVideo 就是要显示的视频窗口的;可以是form ,panel等
//AviPanel.width就是显示的宽度,AviPanel.height显示的高度;
if(capDriverConnect(CapWnd,0)) then

begin

//capOverlay(m_hCapWnd,true);
//普通的摄像头不能用overlay的方式
capPreviewRate(CapWnd,30);
//设置帧率为30
capPreview(CapWnd,true);
// preview方式显示
dwSize:=capGetVideoFormatSize(CapWnd);
capGetVideoFormat(CapWnd,@setBmp, dwSize);
setBmp.bmiHeader.biWidth:=vWin.Width;
//设置捕捉图片的大小了 宽度
setBmp.bmiHeader.biHeight:=vWin.Height;
//设置捕捉图片的大小了 高度
capSetVideoFormat(CapWnd,@setBmp,dwSize);
Result := true;
end
else
begin

if frmCapture<>nil then
//释放
begin

frmCapture.Close;
FreeAndNil(frmCapture);
end;

end;

except
end;

end;

/// <summary>
/// 断开和摄像头的连接
/// </summary>
/// <returns> </returns>
function DisconnectVideo(): boolean;
stdcall;
begin

Result := false;
vWin := nil;
if CapWnd=0 then
exit;
capDriverDisconnect(CapWnd);// vfw里面的标准函数
if Assigned(frmCapture) then

begin

frmCapture.Close;
FreeAndNil(frmCapture);
Result := true;
end;

end;

/// <summary>
/// 抓图,然后把图赋值给Photo,
/// </summary>
/// <param name=&quot;Photo&quot;>抓取的图片 </param>
/// <returns> </returns>
function CaptureFrame(var Photo: TBitmap): boolean;
stdcall;
begin

Result := false;
if CapWnd=0 then
exit;
try
if not capEditCopy(CapWnd) then
exit;
//把图像拷到剪贴板
if not Assigned(Photo) then
exit;
Photo.LoadFromClipboardFormat(CF_BITMAP,Clipboard.GetAsHandle(CF_BITMAP), 0);
Result := true;
except
result := false;
end;

end;
 
自己顶一下,发现不光是最小化,而是只要不是当前窗体,就没法采集,看msdn,提到一个CaptureParms参数,设置里面的fyield参数=true,结果还是不行。
 
在timer 觸發時候
SetactiveWindow(Handle);
//API函数,将本窗体提至最前
FormStyle := fsStayOnTop;
做連接,采集等等動作。
 
欢迎交流:
qq:444094419
 
www.zn123.com
下我的demo试试
也是基于 vfw的
 
后退
顶部