unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,shlobj, ExtCtrls, {TFlatButtonUnit,TFlatPanelUnit,TFlatTitlebarUnit,}
FlatBars, FlatBtns, FlatUtils, FlatPanel;
type
//====================定義窗體類(lèi)==========================//
TForm1 = class(TForm)
//界面控件
open: TOpenDialog; //打開(kāi)對話(huà)框控件
FlatPanel1: TFlatPanel; //FlatPanel控件
Button1: TFlatButton; //按鈕控件
Button2: TFlatButton; //按鈕控件
FlatTitlebar1: TFlatTitlebar; //Titlebar 控件
FlatButton1: TFlatButton; //按鈕控件
FlatButton2: TFlatButton; //按鈕控件
//窗口事件
procedure FormClose(Sender: TObject; var Action: TCloseAction); //窗口關(guān)閉事件
procedure FormShow(Sender: TObject); //窗口顯示事件
procedure Button1Click(Sender: TObject); //Button1的Click事件
procedure Button2Click(Sender: TObject); //Button2的Click事件
procedure FlatButton1Click(Sender: TObject); //FlatButton1的Click事件
procedure FlatButton2Click(Sender: TObject); //FlatButton2的Click事件
private
{ Private declarations }
mtv:widestring; //視頻文件名
public
{ Public declarations }
fillcolor:TColor; //需要填充的顏色
catchcolor:TColor; //需要摳出的顏色
detal:Byte; //顏色誤差范圍
procedure CreatDirectshow; //創(chuàng )建Directshow環(huán)境資源
Procedure FreeDirectshow; //釋放Directshow環(huán)境資源
procedure catchpicture; //捕捉視頻圖象,并做處理
end;
var
Form1: TForm1; //定義窗體對象
implementation
{$R *.dfm}
uses
Directshow9,comobj,DSutil, Unit2; //包含附加的單元。Directshow9為微軟DirectX SDK中Directshow的DELPHI單元文件
//comobj為DELPHI的COM的單元
//DSUtil為DIRECTSHOW的DELPHI工具單元
//Unit2為 設置窗口 的單元
//==================變量定義部分===============//
var
FilterGraph:IGraphBuilder=nil; //Directshow的IGraphBuilder接口,用于Directshow的框架
MediaControl:IMediaControl=nil; //Directshow的IMediaControl接口,用于控制媒體播放,暫停,停止
VideoRender:IBaseFilter=nil; //Directshow的IBaseFilter接口,IBaseFiler是Directshow中所有Filter的基類(lèi).此處是保存的VMR Video Filter
SampleGrabber:ISampleGrabber=nil;//Directshow的ISampleGrabber接口,此接口存在于SampleGrabber Filter上,用這接口可從 SampleGrabber Filter中獲得視頻圖象顏色信息
id:integer=0;//調試所用,用于在DIRECTSHOW SDK自帶的 graphedt工具中申明個(gè)ID ,用于調試。
//===================函數實(shí)現部分===============//
{DELPHI函數格式簡(jiǎn)介:
1.procedure 過(guò)程名稱(chēng) (參數) ; //如果沒(méi)有參數則可以省略"()"
//局部變量申明
var //變量申明系統關(guān)鍵字
MediaRect:TRect;//其中MediaRect為變量名稱(chēng),TRect為變量類(lèi)型
begin
... //函數體部分
...
end; // begin.....end 結構類(lèi)似于C++中的 {.......}
{ 2.function 函數名稱(chēng)(參數):返回值類(lèi)型; //如果沒(méi)有參數則可以省略"()"
//局部變量申明
var //變量申明系統關(guān)鍵字
MediaRect:TRect;//其中MediaRect為變量名稱(chēng),TRect為變量類(lèi)型
begin
... //函數體部分
...
result:=...;//result為返回值變量,不需要自己聲明,它代表函數的返回值變量,":="為DELPHI的賦值符號
end; // begin.....end 結構類(lèi)似于C++中的 {.......}
//}
procedure TForm1.CreatDirectshow;
//函數局部變量申明部分
var
MediaRect:TRect; //區域局部變量,用于設置視頻在窗口顯示的區域
pType:_AMMEDIATYPE; //視頻媒體類(lèi)型變量,用于設置SampleGrabber Filter的接收視頻的類(lèi)型(如告訴系統:接受的為視頻信息,視頻內部圖象格式為RGB32位)
VideoWindow:IVideoWindow; //Directshow的IVideoWindow接口,用于對視頻的顯示窗口做設置(例如:設置其父窗體)
begin
FilterGraph:=CreateComobject(CLSID_FilterGraph) as IGraphBuilder; //創(chuàng )建Directshow中的FilterGraph COM對象并返回IGraphBuilder接口
VideoRender:=createcomobject(CLSID_VideoMixingRenderer) as IBaseFilter; //創(chuàng )建Directshow中的VideoMixingRenderer Filter COM對象并返回IBaseFilter接口
SampleGrabber:=createcomobject(CLSID_SampleGrabber) AS ISampleGrabber; //創(chuàng )建Directshow中的SampleGrabber Filter COM對象并返回ISampleGrabber接口
Filtergraph.AddFilter(VideoRender,‘VideoRender‘); //在Filtregraph框架中添加剛創(chuàng )建的VideoMixingRenderer Filter
FilterGraph.AddFilter(SampleGrabber as IBaseFilter,‘SampleGrabber‘); //在Filtregraph框架中添加剛創(chuàng )建的SampleGrabber Filter
fillchar(ptype,sizeof(_AMMEDIATYPE),0);//對ptype變量初始化
ptype.majortype:=MEDIATYPE_Video;//設置主類(lèi)型為視頻格式
ptype.subtype:=MEDIASUBTYPE_RGB32; //設置輔助類(lèi)型為RGB32(就是接受視頻流為RGB32的,FilterGraph會(huì )智能加入相應的轉換Filter)
ptype.formattype:=FORMAT_VideoInfo; //設置媒體信息格式為FORMAT_VideoInfo格式
SampleGrabber.SetMediaType(pType);//將SampleGrabber Filter的類(lèi)型設置為pType變量所指定的類(lèi)型
SampleGrabber.SetBufferSamples(true);//將SampleGrabber Filter設置為緩沖模式
FilterGraph.RenderFile(pwidechar(mtv),nil); //完成播放指定文件的所有Filter連接
VideoRender.QueryInterface(IID_IVideoWindow, VideoWindow);//從VideoRender中獲得IVideoWindow接口
Videowindow.put_Owner(OAHWND(FlatPanel1.Handle)); //設置視頻窗口的父窗體為FlatPanel控件
Videowindow.put_windowstyle(WS_CHILD or WS_Clipsiblings); //設置視頻窗體為子窗體,剪裁類(lèi)型
Videowindow.put_Left(0);//設置視頻窗體的LEFT
Videowindow.put_Top(0);//設置視頻窗體的TOP
Videowindow.put_Width(FlatPanel1.Width); //設置視頻窗體的Width
Videowindow.put_Height(FlatPanel1.Height);//設置視頻窗體的Height
Videowindow.put_Visible(true); //讓視頻窗體可見(jiàn)
FilterGraph.QueryInterface(IID_IMediaControl,MediaControl);//從FilterGraph中獲得IMediaControl接口
dsutil.AddGraphToRot(filterGraph,id); //注冊GraphEdit所用的ID,可以方便在GraphEdit控件中調試
end;
procedure TForm1.FreeDirectshow;
begin
dsutil.RemoveGraphFromRot(id); //清除在GraphEdit中注冊的ID
if VideoRender<>nil then VideoRender:=nil; //釋放VideoRender
if FilterGraph<>nil then FilterGraph:=nil; //釋放FilterGraph
IF SampleGrabber<>NIL THEN SampleGrabber:=NIL;//釋放SampleGrabber
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
freedirectshow; //釋放Directshow環(huán)境
end;
procedure TForm1.FormShow(Sender: TObject);
begin
open.DefaultExt:=extractfiledir(application.ExeName); //設置打開(kāi)對話(huà)框的打開(kāi)默認路徑,為應用程序的當前路徑
if open.Execute=false then close; //如果沒(méi)有選擇打開(kāi)的文件,則關(guān)閉程序
if trim(open.FileName)=‘‘ then close; //如果打開(kāi)文件的文件名為空,則關(guān)閉程序
if not fileexists(open.FileName) then close; //如果打開(kāi)不存在的文件,則關(guān)閉程序
mtv:=open.FileName; //將打開(kāi)窗口中用戶(hù)選擇的文件的名稱(chēng)賦值給MTV變量
CreatDirectshow; //創(chuàng )建Directshow環(huán)境
end;
//============抓圖處理關(guān)鍵代碼部分==============//
procedure TForm1.catchpicture;
var
ptype:_AMMEDIATYPE; //視頻媒體類(lèi)型變量,詳細介紹見(jiàn),CreateDirectshow函數部分
size:integer;
buf:pchar; //用于存放獲得的視頻數據的緩沖區
bmphead:tagBitmapfileheader;//BMP圖片的文件頭結構體變量
BMPINFO:PBitmapinfoheader;//BMP圖片的文件頭結構體指針變量
bmpcore:tagBITMAPCoreheader; //BMP圖片的Core頭結構體變量
filestream:TFilestream; //DELPHI的文件流類(lèi)型變量
step:integer;
i:integer;
catch,current,fill:integer;
absvalue:integer;
test1,test2,test3,test4,test5,test6:byte;
begin
try
MediaControl.Pause; //播放暫停
SampleGrabber.GetConnectedMediaType(ptype); //獲得SampleGrabber Filter上的輸入PIN上的連接類(lèi)型
size:=0;
buf:=nil;
SampleGrabber.GetCurrentBuffer(size,nil);//獲得SampleGrabber Filter上的緩沖區大小
try
buf:=allocmem(size); //分配buf空間
SampleGrabber.GetCurrentBuffer(size,buf);//獲得視頻的當前數據,保存到buf中
if (ptype.cbFormat=sizeof(VIDEOINFOHEADER)) and (ptype.pbFormat<>nil) and (IsEqualGUID(ptype.formattype,FORMAT_VideoInfo)) then //判斷Sampler Grabber中的輸入Pin上的類(lèi)型是否滿(mǎn)足我們的要求
begin
//=設置bmp Head部分=//
with bmphead do
begin
bftype:=$4d42;
bfsize:=sizeof(tagBitmapfileheader);
bfreserved1:=0;
bfreserved2:=0;
bfOffBits:=bfsize+sizeof(tagBITMAPCoreheader);
end;
bmpinfo:=PBitmapinfoheader(@(PVideoinfoheader(ptype.pbFormat).bmiHeader));
step:=bmpinfo.biBitCount div 8;
bmpcore.bcSize:=sizeof(tagBITMAPCoreheader);
bmpcore.bcWidth:=bmpinfo.biWidth;
bmpcore.bcHeight:=bmpinfo.biHeight;
bmpcore.bcPlanes:=1;
bmpcore.bcBitCount:=bmpinfo.biBitCount;
if catchcolor<>fillcolor then
begin
catch:=COLORTORGB(Catchcolor);
fill:=COLORTORGB(fillcolor);
fill:=RGB(GETBValue(fillcolor),GETGValue(fillcolor),GetRValue(fillcolor));
current:=0;
for i:=0 to bmpinfo.biWidth*bmpinfo.biHeight-1 do//循環(huán)查找視頻圖象顏色中的數據
begin
Current:=PInteger(Pchar(buf)+i*step)^;
if (abs(GetBValue(Current)-GetRValue(catch))<=detal) and (abs(GetGValue(Current)-GetGValue(catch))<=detal) and (abs(GetRValue(Current)-GetBValue(catch))<=detal) then //判斷當前像素中的顏色是否符合摳像填充條件
begin
PInteger(pchar(buf)+i*step)^:=fill;//填充用戶(hù)設置的填充顏色
end;
end;
end;
try
filestream:=TFilestream.Create(Extractfiledir(Application.ExeName)+‘/抓下來(lái)的視頻圖.bmp‘,fmCreate or fmOpenWrite); //創(chuàng )建FileStream視頻流
filestream.WriteBuffer(bmphead,bmphead.bfSize);//將bmphead變量中的數據寫(xiě)入流中
filestream.WriteBuffer(bmpcore,sizeof(tagBITMAPCoreheader)); //將bmpcore變量中的數據寫(xiě)入流中
filestream.WriteBuffer(buf^,size); //將buf指針所指向的數據寫(xiě)入流中
windows.MessageBox(handle,‘抓圖成功!‘,‘提示‘,MB_ICONINFORMATION);//提示用戶(hù),抓圖成功
finally
filestream.Free;//釋放Filestream視頻流
end;
end;
finally
freemem(buf); //釋放Buf所占用的空間
end;
finally
MediaControl.Run;//重新播放
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
MediaControl.Run;//播放視頻
button1.Enabled:=false; //將Button1按鈕設為不可用
button2.Enabled:=true; //將Button2按鈕設置為可用
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
catchpicture(); //調用自己編寫(xiě)的抓圖處理函數
end;
procedure TForm1.FlatButton1Click(Sender: TObject);
begin
close; //關(guān)閉窗體,也將關(guān)閉程序
end;
procedure TForm1.FlatButton2Click(Sender: TObject);
begin
form2.ShowModal;//顯示FORM2窗體(模態(tài)顯示,也就是你必須關(guān)閉了FORM2,才能操作程序的其他窗體)
end;
end.

