VFW视频编程回调函数没获得图像

kitty1kitty 2011-08-11 11:58:28
为什么在回调函数FrameCallBack中用于获得视频数据的lpVHdr中没有图像,检测到的长度只为4,


unit Unit1;

interface

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

type
TFrmMain = class(TForm)
Button1: TButton;
Panel1: TPanel;
Image1: TImage;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
CaptureHandle: THandle;
BmpInfo: TBitmapInfo;
procedure CompareFrame(lpVHdr: PVIDEOHDR);
public
{ Public declarations }
end;

var
FrmMain: TFrmMain;


implementation

{$R *.dfm}

procedure TFrmMain.FormCreate(Sender: TObject);
begin
CaptureHandle := 0;
end;

procedure GetUsbCamerBmpSize(var BmpInfoHeader: TBitmapinfoheader);
var
PBmpInfoHeader: PBitmapInfo;
dwSize: DWORD;
begin
dwSize := capGetVideoFormatSize(FrmMain.CaptureHandle);
PBmpInfoHeader := GlobalAllocPtr(GHND, dwSize);
capGetVideoFormat(FrmMain.CaptureHandle, PBmpInfoHeader, dwSize);
CopyMemory(@BmpInfoHeader, @PBmpInfoHeader.bmiHeader, Sizeof(TBitmapinfoheader));
GlobalFreePtr(PBmpInfoHeader);
end;

procedure TFrmMain.CompareFrame(lpVHdr: PVIDEOHDR);
var
BmpFileHeader: TBitmapFileHeader;
BmpInfoHeader: TBitmapInfoHeader;
MyMemoryStream: TMemoryStream;
MyBmp: TBitmap;
MyJpg: TJPEGImage;
begin
Caption := FrmMain.Caption+'=B='+inttostr(sizeof(lpVHdr));
FillChar(BmpFileHeader, Sizeof(TBitmapfileheader), 0);
FillChar(BmpInfoHeader, Sizeof(TBitmapinfoheader), 0);

BmpFileHeader.bfType := $4D42; //文件类型,必须为BM.
BmpFileHeader.bfSize := BmpInfo.bmiHeader.biSizeImage; //BMP数据的大小字节
BmpFileHeader.bfReserved1 := 0; //保留,必需为0
BmpFileHeader.bfReserved2 := 0; //保留,必需为0
BmpFileHeader.bfOffBits := Sizeof(TBitmapFileHeader) + Sizeof(TBitmapInfoHeader); //Specifies the offset, in bytes, from the BITMAPFILEHEADER structure to the bitmap bits.

GetUsbCamerBmpSize(BmpInfoHeader);

Panel1.Left := 0;
Panel1.Top := 0;
Panel1.ClientWidth := BmpInfoHeader.biWidth;
Panel1.ClientHeight := BmpInfoHeader.biHeight;

MyBmp := TBitmap.Create;
MyJpg := TJPEGImage.Create;
MyMemoryStream := TMemoryStream.Create;
FrmMain.Caption := FrmMain.Caption+'=C='+inttostr(BmpInfo.bmiHeader.biSizeImage);
MyMemoryStream.Write(BmpFileHeader, sizeof(BmpFileHeader));
MyMemoryStream.Write(BmpInfoHeader, sizeof(BmpInfoHeader));
MyMemoryStream.Write(lpVHdr^.lpData, BmpInfo.bmiHeader.biSizeImage);
MyMemoryStream.Position := 0;

MyBmp.LoadFromStream(MyMemoryStream);

with MyBmp.Canvas do
begin
Brush.style := bsClear;
Font.Color := clRed; // 文字前景色
Font.Size := 20; //TxtFont.Size;//10;//Self.Font.Size;
//Font.Name := Self.Font.Name;
TextOut(0, 0, DateTimeToStr(Now)); //else
//if RadioButton3.Checked then TextOut(0,0,Edit1.Text);
end;

Image1.Picture.Bitmap.Assign(MyBmp);
MyJpg.Assign(MyBmp);
MyJpg.CompressionQuality := 65;
MyMemoryStream.Clear;
MyJpg.SaveToStream(MyMemoryStream);
MyMemoryStream.Position := 0;
//SendVideoBufToClient(MyMemoryStream);//发送数据出去
MyMemoryStream.Free;
MyBmp.Free;
MyJpg.Free;
end;


function FrameCallBack(hWnd: HWND; lpVHdr: PVIDEOHDR): DWORD; stdcall;
begin
FrmMain.Caption := FrmMain.Caption+'=A='+inttostr(sizeof(lpVHdr));
FrmMain.CompareFrame(lpVHdr);
Result := DWORD(True);
end;


procedure TFrmMain.Button1Click(Sender: TObject);
var
CapParms: TCAPTUREPARMS;
begin
//把视频输入格式保存在BimpInfo中
FillChar(BmpInfo.bmiHeader, SizeOf(TBitmapInfoHeader), 0);
with BmpInfo.bmiHeader do
begin
biBitCount := 24;
biClrImportant := 0;
biClrUsed := 0;
biCompression := BI_RGB;
biHeight := 240;
biPlanes := 1;
biSize := SizeOf(TBitmapInfoHeader);
biSizeImage := 0;
biWidth := 320;
biXPelsPerMeter := 0;
biYPelsPerMeter := 0;
end;

//创建一个AVICap捕获窗口
CaptureHandle := capCreateCaptureWindow(
'Capture Window',
WS_VISIBLE or WS_CHILD,
0,
0,
320,//Panel1.Width,
240,//Panel1.Height,
Handle,
0);

if CaptureHandle = 0 then
begin
ShowMessage('创建窗口失败!');
Exit;
end;
if not capDriverConnect(CaptureHandle, 0) then //连接摄像头.0代表第一个摄像头
begin
ShowMessage('打开摄像头失败!');
Exit;
end;

capSetVideoFormat(CaptureHandle, @BmpInfo, SizeOf(BmpInfo)); //设置视频格式
capPreviewRate(CaptureHandle, 60); //设置预览视频的频率
capSetCallbackOnVideoStream(CaptureHandle, @FrameCallBack); //设置回调函数.采用“流格式”
//capSetCallbackOnFrame(CaptureHandle, @FrameCallBack);//设置回调函数,采用“帧格式”

capCaptureGetSetup(CaptureHandle, @CapParms, sizeof(TCAPTUREPARMS)); //获取当前设置
CapParms.fYield := TRUE;
CapParms.fAbortLeftMouse := FALSE;
CapParms.fAbortRightMouse := FALSE;
capCaptureSetSetup(CaptureHandle, @CapParms, sizeof(TCAPTUREPARMS)); //改变需要改变的参数

capCaptureSequenceNoFile(CaptureHandle); //不保存文件
//CapPreview(CaptureHandle,true);

end;


procedure TFrmMain.Button2Click(Sender: TObject);
begin
if CaptureHandle <> 0 then
begin
CapCaptureStop(CaptureHandle); //停止捕获
//capSetCallbackOnFrame(CaptureHandle,nil);
capDriverDisconnect(CaptureHandle); //断开连接
end;
end;

end.

...全文
161 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
kitty1kitty 2011-08-12
  • 打赏
  • 举报
回复
自己顶一个
kitty1kitty 2011-08-12
  • 打赏
  • 举报
回复
我没资源分了
贝隆 2011-08-12
  • 打赏
  • 举报
回复
http://download.csdn.net/source/2979383
我有一个VB的例子,给你参考一下:
kitty1kitty 2011-08-12
  • 打赏
  • 举报
回复
高手帮忙看看啊

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧