Q
question
Unregistered / Unconfirmed
GUEST, unregistred user!
使用 DSPack 控件包(ver 2.3),作了监视程序,平时屏幕上仅仅显示摄像头采集的信息,不保存为磁盘文件,在需要的时候按一个按钮保存当前画面到一个指定的图片文件中。
现在的问题是,前面一部分都完成,就是不知道如何获取实时采集的图像。
程序部分代码如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DSPack, DSUtil, DirectShow9, ExtCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
VideoCapFilters: TListBox;
Label3: TLabel;
VideoFormats: TListBox;
VideoSourceFilter: TFilter;
CaptureGraph: TFilterGraph;
VideoWindow: TVideoWindow;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
Image1: TImage;
procedure VideoCapFiltersClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
CapEnum: TSysDevEnum;
VideoMediaTypes: TEnumMediaType;
implementation
{$R *.dfm}
procedure TForm1.VideoCapFiltersClick(Sender: TObject);
var
PinList: TPinList;
i: integer;
begin
CapEnum.SelectGUIDCategory(CLSID_VideoInputDeviceCategory);
if VideoCapFilters.ItemIndex <> -1 then
begin
VideoSourceFilter.BaseFilter.Moniker := CapEnum.GetMoniker(VideoCapFilters.ItemIndex);
VideoSourceFilter.FilterGraph := CaptureGraph;
CaptureGraph.Active := true;
PinList := TPinList.Create(VideoSourceFilter as IBaseFilter);
VideoFormats.Clear;
VideoMediaTypes.Assign(PinList.First);
for i := 0 to VideoMediaTypes.Count - 1 do
VideoFormats.Items.Add(VideoMediaTypes.MediaDescription);
CaptureGraph.Active := false;
PinList.Free;
// StartButton.Enabled := true;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i: integer;
begin
CapEnum := TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
for i := 0 to CapEnum.CountFilters - 1 do
VideoCapFilters.Items.Add(CapEnum.Filters.FriendlyName);
VideoMediaTypes := TEnumMediaType.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
CaptureGraph.Stop;
CapEnum.Free;
VideoMediaTypes.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
multiplexer: IBaseFilter;
// Writer: IFileSinkFilter;
PinList: TPinList;
// i: integer;
BV : IBasicVideo;
X, Y : Integer;
begin
// Activate the filter graph, at this stage the source filters are added to the graph
CaptureGraph.Active := true;
// configure output Video media type
if VideoSourceFilter.FilterGraph <> nil then
begin
PinList := TPinList.Create(VideoSourceFilter as IBaseFilter);
if VideoFormats.ItemIndex <> -1 then
with (PinList.First as IAMStreamConfig) do
SetFormat(VideoMediaTypes.Items[VideoFormats.ItemIndex].AMMediaType^);
PinList.Free;
end;
with CaptureGraph as IcaptureGraphBuilder2 do
begin
if VideoSourceFilter.BaseFilter.DataLength > 0 then
RenderStream(@PIN_CATEGORY_PREVIEW, nil, VideoSourceFilter as IBaseFilter,
nil , VideoWindow as IBaseFilter);
if VideoSourceFilter.FilterGraph <> nil then
RenderStream(@PIN_CATEGORY_CAPTURE, nil, VideoSourceFilter as IBaseFilter,
nil, multiplexer as IBaseFilter);
end;
//获取视频的实际大小
CaptureGraph.QueryInterface(IBasicVideo,BV);
BV.get_VideoWidth(X);
BV.get_VideoHeight(Y);
VideoWindow.Width := X;
VideoWindow.Height := Y;
Image1.Width := X;
Image1.Height := Y;
CaptureGraph.Play;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
CaptureGraph.Stop;
CaptureGraph.Active := False;
end;
end.
尝试使用 SampleGrabber 但好像 SampleGrabber 只能获取 FilterGraph 的Mode属性为 gmNormal 的图像,如果Mode被设置成了gmCapture 就无法获取了。
现在的问题是,前面一部分都完成,就是不知道如何获取实时采集的图像。
程序部分代码如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DSPack, DSUtil, DirectShow9, ExtCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
VideoCapFilters: TListBox;
Label3: TLabel;
VideoFormats: TListBox;
VideoSourceFilter: TFilter;
CaptureGraph: TFilterGraph;
VideoWindow: TVideoWindow;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
Image1: TImage;
procedure VideoCapFiltersClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
CapEnum: TSysDevEnum;
VideoMediaTypes: TEnumMediaType;
implementation
{$R *.dfm}
procedure TForm1.VideoCapFiltersClick(Sender: TObject);
var
PinList: TPinList;
i: integer;
begin
CapEnum.SelectGUIDCategory(CLSID_VideoInputDeviceCategory);
if VideoCapFilters.ItemIndex <> -1 then
begin
VideoSourceFilter.BaseFilter.Moniker := CapEnum.GetMoniker(VideoCapFilters.ItemIndex);
VideoSourceFilter.FilterGraph := CaptureGraph;
CaptureGraph.Active := true;
PinList := TPinList.Create(VideoSourceFilter as IBaseFilter);
VideoFormats.Clear;
VideoMediaTypes.Assign(PinList.First);
for i := 0 to VideoMediaTypes.Count - 1 do
VideoFormats.Items.Add(VideoMediaTypes.MediaDescription);
CaptureGraph.Active := false;
PinList.Free;
// StartButton.Enabled := true;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i: integer;
begin
CapEnum := TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
for i := 0 to CapEnum.CountFilters - 1 do
VideoCapFilters.Items.Add(CapEnum.Filters.FriendlyName);
VideoMediaTypes := TEnumMediaType.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
CaptureGraph.Stop;
CapEnum.Free;
VideoMediaTypes.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
multiplexer: IBaseFilter;
// Writer: IFileSinkFilter;
PinList: TPinList;
// i: integer;
BV : IBasicVideo;
X, Y : Integer;
begin
// Activate the filter graph, at this stage the source filters are added to the graph
CaptureGraph.Active := true;
// configure output Video media type
if VideoSourceFilter.FilterGraph <> nil then
begin
PinList := TPinList.Create(VideoSourceFilter as IBaseFilter);
if VideoFormats.ItemIndex <> -1 then
with (PinList.First as IAMStreamConfig) do
SetFormat(VideoMediaTypes.Items[VideoFormats.ItemIndex].AMMediaType^);
PinList.Free;
end;
with CaptureGraph as IcaptureGraphBuilder2 do
begin
if VideoSourceFilter.BaseFilter.DataLength > 0 then
RenderStream(@PIN_CATEGORY_PREVIEW, nil, VideoSourceFilter as IBaseFilter,
nil , VideoWindow as IBaseFilter);
if VideoSourceFilter.FilterGraph <> nil then
RenderStream(@PIN_CATEGORY_CAPTURE, nil, VideoSourceFilter as IBaseFilter,
nil, multiplexer as IBaseFilter);
end;
//获取视频的实际大小
CaptureGraph.QueryInterface(IBasicVideo,BV);
BV.get_VideoWidth(X);
BV.get_VideoHeight(Y);
VideoWindow.Width := X;
VideoWindow.Height := Y;
Image1.Width := X;
Image1.Height := Y;
CaptureGraph.Play;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
CaptureGraph.Stop;
CaptureGraph.Active := False;
end;
end.
尝试使用 SampleGrabber 但好像 SampleGrabber 只能获取 FilterGraph 的Mode属性为 gmNormal 的图像,如果Mode被设置成了gmCapture 就无法获取了。