话题1063839的标题是: 求WDM的视频捕获(单桢BMP、AVI录像)控件 (288分)
分类:图形图象 qdyoung (2002-04-23 21:08:00)
可以基于DirectShow
DSPack我看过,在没有安装Service Pack2的Windows 2000下 Grabber&WDM 例子不能用。
Delphi-jedi里的TCapture也一样。
有没有简单点的,只要捕获功能,最好不要求非要DirectX 8。
房客 (2002-04-26 7:47:00)
TCapture怎么不行了?
qdyoung (2002-04-26 10:56:00)
只有DSPack可以用,但保存的BMP图片只有300多x200多,
有没办法让保存的BMP图片与显示窗口一样大小?
还有就是怎么显示 调整视频卡参数的亮度等的对话框?
qdyoung (2002-04-26 11:01:00)
只有DSPack可以用,但保存的BMP图片只有300多x200多,
有没办法让保存的BMP图片与显示窗口一样大小?
还有就是怎么显示 调整视频卡参数的亮度等的对话框?
zl (2002-05-24 11:13:00)
[
]
qdyoung (2002-06-06 18:49:00)
up
Singgreen (2002-06-21 20:33:00)
关注
ChinaD (2002-06-21 22:04:00)
影片的尺寸只有300多x200多啊,所以保存的只有这么大。
想要全屏幕的可以自己放大啊,TPicture就可以实现图片的伸缩。
想要多大就有多大,哈哈。 :D
qdyoung (2002-06-21 22:06:00)
播放时directx的放大效果很好,自己用image伸缩不行,有锯齿
LeeChange (2002-08-09 14:30:00)
兄台此言差矣,directx放大用的是显卡的x,y轴放大,硬件实现,效果自然很好.可实际的图像数据
还是352x288(PAL),怎么也不会随着显示的改变而改变.除非采集时就设为640x480.
qdyoung (2002-08-09 14:50:00)
我就是想把显示出来的(硬件放大过的)图象保存下来,而不是保存352x288的图片,
不知道通过WDM怎样做到
LeeChange (2002-08-09 14:56:00)
此路不通.
可以参见以前关于Overlay表面截屏的讨论(前前后后有好上万分,其中也有我的贡献),到如今没有好的方法.
qdyoung (2002-08-09 15:12:00)
我对Direct那一套不是很熟
那能不能对保存下来352x288图片任意放大显示,就像捕获以前的显示效果
LeeChange (2002-08-09 15:15:00)
这条路到是通的.
但你对Direct那一套不是很熟,就等于不通.
qdyoung (2002-08-09 15:34:00)
正在努力学习
但打印时要放大又怎么办呢
y_peijun (2002-10-25 19:29:00)
我用天敏卡的可以CAPTURE 7..X5.. http://www.10moons.com
t163t163 (2002-11-09 8:33:00)
to qdyoung、房客:
DSPack 是什么东西,我先手上也有一个WDM卡,用TVideoCap控件进行捕捉,也捕捉不到,
我想知道是怎么回事,用DSPACK可以吗,在哪里可以下载呢?
谢谢!
Net200 (2002-11-11 20:50:00)
使用微软的VFW
具体步骤如下
1.创建“捕获窗”
在进行视频捕获之前必需要先创建一个“捕获窗”,并以它为基础进行所有的捕获及设置操作。“捕获窗”用AVICap窗口类的“CapCreateCaptureWindow”函数来创建,其窗口风格一般为WS_CHILD和WS_VISIBLE。
捕获窗类似于标准控件(如按钮、列表框等),并具有下列功能:
●将视频流和音频流捕获到一个AVI文件中;
●动态地同视频和音频输入器件连接或断开;
●以Overlay或Preview模式对输入的视频流进行实时显示;
●在捕获时,可指定所用的文件名并能将捕获文件的内容拷贝到另一个文件;
●设置捕获速率;
●显示控制视频源、视频格式、视频压缩的对话框;
●创建、保存或载入调色板;
●将图像和相关的调色板拷贝到剪贴板;
●将捕获的单帧图像保存为DIB格式的文件。
2.关联捕获窗和驱动程序
单独定义的一个捕获窗是不能工作的,它必需与一个设备相关联,这样才能取得视频信号。用函数CapDriverConnect可使一个捕获窗与一个设备驱动程序相关联。
3.设置视频设备的属性
通过设置TcaptureParms结构变量的各个成员变量,可以控制设备的采样频率、中断采样按键、状态行为等等。设置好TCaptureParms结构变量后,可以用函数CapCaptureSetSetup使设置生效。之后还可以用CapPreviewScale、CapPreviewRate来设置预览的比例与速度,也可以直接使用设备的默认值。
4.打开预览
利用函数CapOverlay选择是否采用叠加模式预览,这样占用系统资源小,并且视频显示速度快。然后用CapPreview启动预览功能,这时就可以在屏幕上看到来自摄像机的图像了。
通过以上4步就可以建立一个基本的视频捕获程序。但如果想自已处理从设备捕获到的视频数据,则要使用捕获窗回调函数来处理,比如一帧一帧地获得视频数据或以流的方式获得视频数据等等。
实例编程
下面以一个一帧一帧地从视频设备上捕获视频数据的Delphi程序为例,来说明每个函数的作用以及开发过程。
该程序的功能是可以在屏幕上显视捕获到的视频,并可以获得每一帧的图像数据。
新建一个工程,并将AVICAP32.PAS包含到USES中。
在Form1上放置一个TPanel控件,设Name为“gCapVideoArea”,该控件用于显示视频。再放置两个TButton控件,一个Name为“Openvideo”,另一个Name为“Closevideo”。
定义全局变量:
var
//定义捕获窗句柄
ghCapWnd: THandle;
//可以得到视频数据指针的结构变量,用于回调函数中
VideoStr: LPVIDEOHDR;
//用于设置设备属性的结构变量
CapParms: TCaptureParms;
在Name为“Openvideo”的TButton 的Click事件中写入以下代码:
procedure TForm1.OpenvideoClick(Sender: TObject);
begin
//使用Tpanel控件来创建捕获窗口
ghCapWnd := CapCreateCaptureWindow
( PChar(‘KruwoSoft'), //捕获窗口的名字
WS_CHILD or WS_VISIBLE,//窗口样式
0, //X坐标
0, //Y坐标
gCapVideoArea.Width, //窗口宽
gCapVideoArea.Height, //窗口高
gCapVideoArea.Handle, //窗口句柄
0);
//一般为0
{为了能够捕获视频帧,要启动一个捕获帧回调函数VideoStreamCallBack。捕获一个视频流或当前设备状态时分别使用以下函数:
//捕获一个视频流
CapSetCallbackOnVideoStream;
//得到一个设备错误
CapSetCallbackOnError;
//得到一个设备状态
CapSetCallbackOnStatus
}
//定义一个帧捕获回调函数
CapSetCallbackOnFrame (ghCapWnd,LongInt(@VideoStreamCallBack));
//将一个捕获窗口与一个设备驱程相关联,第二个参数是个序号,当系统中装有多个显视驱动程序时,其值分别依次为0到总个数
CapDriverConnect(ghCapWnd, 0);
//设置设备属性的结构变量
CapParms.dwRequestMicroSecPerFrame:=40000;
CapParms.fLimitEnabled := FALSE;
CapParms.fCaptureAudio := FALSE;
// NO Audio
CapParms.fMCIControl := FALSE;
CapParms.fYield := TRUE;
CapParms.vKeyAbort := VK_ESCAPE;
CapParms.fAbortLeftMouse := FALSE;
CapParms.fAbortRightMouse := FALSE;
//使设置生效
CapCaptureSetSetup(ghCapWnd,LongInt(@CapParms),sizeof(TCAPTUREPARMS));
//设置预览时的比例
CapPreviewScale(ghCapWnd, 1);
//设置预览时的帧频率
CapPreviewRate(ghCapWnd,66);
//如果要捕获视频流,则要使用函数指定不生成文件。否则将会自动生成AVI文件
CapCaptureSequenceNoFile(ghCapWnd);
//指定是否使用叠加模式,使用为1,否则为0
CapOverlay(ghCapWnd, 1);
//打开预览
CapPreview(ghCapWnd, 1);
end;
在Name为“Closevideo”的TButton 的Click事件中写入以下代码:
procedure TForm1.ClosevideoClick(Sender: TObject);
begin
//停止捕获
capCaptureAbort(ghCapWnd);
//将捕获窗同驱动器断开
capDriverDisconnect(ghCapWnd);
end;
定义捕获帧回调函数:
function FrameCallBack(hWnd:HWND;
lpVHdr:LongInt) :LongInt;
stdcall;
var
DataPoint:^byte;
DibLen,RectWidth,RectHeight:integer;
begin
//转换从回调函数中得到的指针
VideoStr:=LPVIDEOHDR(lpVHdr);
//得到返回的数据大小
DibLen:=VideoStr^.dwBufferLength;
GetMem(DataPoint,64000);
//将帧数据COPY到一个内存中,注意DATAPOINT要先分配空间
CopyMemory(DataPoint,VideoStr^.lpData,Diblen);
//一些其他处理
……
end;
灵活地使用AVICap窗口类的回调函数可以满足各种不同的需求,但要注意从视频卡中捕获的视频数据的格式和图像的长宽要参考视频卡的参数。而且有些视频卡通过设置可支持多种的格式和图像长宽,所以在还原图像时要注意参考所用的视频卡的参数。
--------------------------------------------------------------------------------
视频采集,存成avi
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
OpenVideo: TButton;
CloseVideo: TButton;
GrabFrame: TButton;
SaveBMP: TButton;
StartAVI: TButton;
StopAVI: TButton;
SaveDialog1: TSaveDialog;
procedure FormCreate(Sender: TObject);
procedure OpenVideoClick(Sender: TObject);
procedure CloseVideoClick(Sender: TObject);
procedure GrabFrameClick(Sender: TObject);
procedure SaveBMPClick(Sender: TObject);
procedure StartAVIClick(Sender: TObject);
procedure StopAVIClick(Sender: TObject);
private
{ Private declarations }
hWndC : THandle;
CapturingAVI : bool;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
const WM_CAP_START = WM_USER;
const WM_CAP_STOP = WM_CAP_START + 68;
const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
const WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
const WM_CAP_SAVEDIB = WM_CAP_START + 25;
const WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
const WM_CAP_SEQUENCE = WM_CAP_START + 62;
const WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;
function capCreateCaptureWindowA(lpszWindowName : PCHAR;
dwStyle : longint;
x : integer;
y : integer;
nWidth : integer;
nHeight : integer;
ParentWin : HWND;
nId : integer): HWND;
STDCALL EXTERNAL 'AVICAP32.DLL';
procedure TForm1.FormCreate(Sender: TObject);
begin
CapturingAVI := false;
hWndC := 0;
SaveDialog1.Options :=
[ofHideReadOnly, ofNoChangeDir, ofPathMustExist]
end;
procedure TForm1.OpenVideoClick(Sender: TObject);
begin
hWndC := capCreateCaptureWindowA('My Own Capture Window',
WS_CHILD or WS_VISIBLE ,
Panel1.Left,
Panel1.Top,
Panel1.Width,
Panel1.Height,
Form1.Handle,
0);
if hWndC <> 0 then
SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
end;
procedure TForm1.CloseVideoClick(Sender: TObject);
begin
if hWndC <> 0 then
begin
SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
hWndC := 0;
end;
end;
procedure TForm1.GrabFrameClick(Sender: TObject);
begin
if hWndC <> 0 then
SendMessage(hWndC, WM_CAP_GRAB_FRAME, 0, 0);
end;
procedure TForm1.SaveBMPClick(Sender: TObject);
begin
if hWndC <> 0 then
begin
SaveDialog1.DefaultExt := 'bmp';
SaveDialog1.Filter := 'Bitmap files (*.bmp)|*.bmp';
if SaveDialog1.Execute then
SendMessage(hWndC,
WM_CAP_SAVEDIB,
0,
longint(pchar(SaveDialog1.FileName)));
end;
end;
procedure TForm1.StartAVIClick(Sender: TObject);
begin
if hWndC <> 0 then
begin
SaveDialog1.DefaultExt := 'avi';
SaveDialog1.Filter := 'AVI files (*.avi)|*.avi';
if SaveDialog1.Execute then
begin
CapturingAVI := true;
SendMessage(hWndC,
WM_CAP_FILE_SET_CAPTURE_FILEA,
0,
Longint(pchar(SaveDialog1.FileName)));
SendMessage(hWndC, WM_CAP_SEQUENCE, 0, 0);
end;
end;
end;
procedure TForm1.StopAVIClick(Sender: TObject);
begin
if hWndC <> 0 then
begin
SendMessage(hWndC, WM_CAP_STOP, 0, 0);
CapturingAVI := false;
end;
end;
end.
t163t163 (2002-11-21 12:34:00)
to net200:
太好了,但哪里可以找到avicap32.pas文件呢?
谢谢!
t163t163@163.net
doll_paul (2002-11-21 13:04:00)
gz
yuming_wu (2002-11-21 14:33:00)
我有一个,你可以给我来邮件
yuming_wu@msn.com
blackbook (2002-11-25 18:02:00)
我个人强烈建议用direcetshow,例子太多了。 要方便的话用的dspack 一个很不错的控件
只要装了direcet8.0 都可以用 很方便。
<< 在没有安装Service Pack2的Windows 2000下 Grabber&WDM 例子不能用。
这是因为 你的程序有问题,真的 都能用。
t163t163 (2002-11-26 14:09:00)
to yuming_wu:
谢谢,我已经收到了.
zhoufujin (2002-11-26 20:13:00)
To yuming_wu:
我也需要那个Pas文件,给我也来一个吧,谢谢。
gswzhoufujin@163.com
w8zz (2003-03-27 10:57:00)
如果要捉Overlay表面的视频,要写显卡镜像驱动,DDK里有现成的例子
qdyoung (2003-06-13 11:40:00)
DirectShow 的Delphi例子也可
qdyoung (2003-07-15 13:00:00)
接受答案了.
blackbook的回答最终被接受。