📄 mainform.cs
字号:
bool GetInterfaces()
{
Type comType = null;
object comObj = null;
try {
comType = Type.GetTypeFromCLSID( Clsid.FilterGraph );
if( comType == null )
throw new NotImplementedException( @"DirectShow FilterGraph not installed/registered!" );
comObj = Activator.CreateInstance( comType );
graphBuilder = (IGraphBuilder) comObj; comObj = null;
Guid clsid = Clsid.CaptureGraphBuilder2;
Guid riid = typeof(ICaptureGraphBuilder2).GUID;
comObj = DsBugWO.CreateDsInstance( ref clsid, ref riid );
capGraph = (ICaptureGraphBuilder2) comObj; comObj = null;
comType = Type.GetTypeFromCLSID(Clsid.SampleGrabber);
if (comType == null)
throw new NotImplementedException(@"DirectShow SampleGrabber not installed/registered!");
comObj = Activator.CreateInstance(comType);
sampGrabber = (ISampleGrabber)comObj; comObj = null;
mediaCtrl = (IMediaControl) graphBuilder;
videoWin = (IVideoWindow) graphBuilder;
mediaEvt = (IMediaEventEx) graphBuilder;
baseGrabFlt = (IBaseFilter)sampGrabber;
return true;
}
catch( Exception ee )
{
MessageBox.Show( this, "Could not get interfaces\r\n" + ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop );
return false;
}
finally
{
if( comObj != null )
Marshal.ReleaseComObject( comObj ); comObj = null;
}
}
/// <summary> create the user selected capture device. </summary>
bool CreateCaptureDevice( UCOMIMoniker mon )
{
object capObj = null;
try {
Guid gbf = typeof( IBaseFilter ).GUID;
mon.BindToObject( null, null, ref gbf, out capObj );
capFilter = (IBaseFilter) capObj; capObj = null;
return true;
}
catch( Exception ee )
{
MessageBox.Show( this, "Could not create capture device\r\n" + ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop );
return false;
}
finally
{
if( capObj != null )
Marshal.ReleaseComObject( capObj ); capObj = null;
}
}
/// <summary> make the video preview window to show in videoPanel. </summary>
bool SetupVideoWindow()
{
int hr;
try {
// Set the video window to be a child of the main window
hr = videoWin.put_Owner( videoPanel.Handle );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
// Set video window style
hr = videoWin.put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
// Use helper function to position video window in client rect of owner window
ResizeVideoWindow();
// Make the video window visible, now that it is properly positioned
hr = videoWin.put_Visible( DsHlp.OATRUE );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
hr = mediaEvt.SetNotifyWindow( this.Handle, WM_GRAPHNOTIFY, IntPtr.Zero );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
return true;
}
catch( Exception ee )
{
MessageBox.Show( this, "Could not setup video window\r\n" + ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop );
return false;
}
}
/// <summary> the videoPanel is resized. </summary>
private void videoPanel_Resize(object sender, System.EventArgs e)
{
ResizeVideoWindow();
}
/// <summary> if the videoPanel is resized, adjust video preview window. </summary>
void ResizeVideoWindow()
{
if( videoWin != null )
{
Rectangle rc = videoPanel.ClientRectangle;
videoWin.SetWindowPosition( 0, 0, rc.Right, rc.Bottom );
}
}
/// <summary> override window fn to handle graph events. </summary>
protected override void WndProc( ref Message m )
{
if( m.Msg == WM_GRAPHNOTIFY )
{
if( mediaEvt != null )
OnGraphNotify();
return;
}
base.WndProc( ref m );
}
/// <summary> graph event (WM_GRAPHNOTIFY) handler. </summary>
void OnGraphNotify()
{
DsEvCode code;
int p1, p2, hr = 0;
do
{
hr = mediaEvt.GetEvent( out code, out p1, out p2, 0 );
if( hr < 0 )
break;
hr = mediaEvt.FreeEventParams( code, p1, p2 );
}
while( hr == 0 );
}
/// <summary> do cleanup and release DirectShow. </summary>
void CloseInterfaces()
{
int hr;
try {
#if DEBUG
if( rotCookie != 0 )
DsROT.RemoveGraphFromRot( ref rotCookie );
#endif
if( mediaCtrl != null )
{
hr = mediaCtrl.Stop();
mediaCtrl = null;
}
if( mediaEvt != null )
{
hr = mediaEvt.SetNotifyWindow( IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero );
mediaEvt = null;
}
if( videoWin != null )
{
hr = videoWin.put_Visible( DsHlp.OAFALSE );
hr = videoWin.put_Owner( IntPtr.Zero );
videoWin = null;
}
if( capGraph != null )
Marshal.ReleaseComObject( capGraph ); capGraph = null;
if( graphBuilder != null )
Marshal.ReleaseComObject( graphBuilder ); graphBuilder = null;
if( capFilter != null )
Marshal.ReleaseComObject( capFilter ); capFilter = null;
if( capDevices != null )
{
foreach( DsDevice d in capDevices )
d.Dispose();
capDevices = null;
}
}
catch( Exception )
{}
}
/// <summary> flag to detect first Form appearance </summary>
private bool firstActive;
/// <summary> file name for AVI. </summary>
private string fileName;
/// <summary> list of installed video devices. </summary>
private ArrayList capDevices;
/// <summary> base filter of the actually used video devices. </summary>
private IBaseFilter capFilter;
/// <summary> graph builder interface. </summary>
private IGraphBuilder graphBuilder;
/// <summary> capture graph builder interface. </summary>
private ICaptureGraphBuilder2 capGraph;
private ISampleGrabber sampGrabber;
/// <summary> video window interface. </summary>
private IVideoWindow videoWin;
/// <summary> control interface. </summary>
private IMediaControl mediaCtrl;
/// <summary> event interface. </summary>
private IMediaEventEx mediaEvt;
private IBaseFilter baseGrabFlt;
private VideoInfoHeader videoInfoHeader;
private bool captured = true;
private int bufferedSize;
private byte[] savedArray;
private const int WM_GRAPHNOTIFY = 0x00008001; // message from graph
private const int WS_CHILD = 0x40000000; // attributes for video window
private const int WS_CLIPCHILDREN = 0x02000000;
private const int WS_CLIPSIBLINGS = 0x04000000;
private delegate void CaptureDone();
#if DEBUG
private int rotCookie = 0;
internal enum PlayState
{
Init, Stopped, Paused, Running
}
private void videoPanel_Paint(object sender, PaintEventArgs e)
{
}
private void toolBar1_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
{
Trace.WriteLine("!!BTN: toolBar_ButtonClick");
int hr;
if (sampGrabber == null)
return;
if (e.Button == toolBarBtnGrab)
{
Trace.WriteLine("!!BTN: toolBarBtnGrab");
if (savedArray == null)
{
//int size = videoInfoHeader.BmiHeader.ImageSize;
int size = 230400;
if ((size < 1000) || (size > 16000000))
return;
savedArray = new byte[size + 64000];
}
toolBarBtnSave.Enabled = true;
Image old = pictureBox.Image;
pictureBox.Image = null;
if (old != null)
old.Dispose();
toolBarBtnGrab.Enabled = true;
captured = true;
hr = sampGrabber.SetCallback(this, 1);
String fileName = "f:/1.bmp";
//pictureBox.Image.Save(sd.FileName, ImageFormat.Bmp);
//pictureBox.Image.Save(fileName,ImageFormat.Bmp);
}
else if (e.Button == toolBarBtnSave)
{
Trace.WriteLine("!!BTN: toolBarBtnSave");
SaveFileDialog sd = new SaveFileDialog();
sd.FileName = @"DsNET.bmp";
sd.Title = "Save Image as...";
sd.Filter = "Bitmap file (*.bmp)|*.bmp";
sd.FilterIndex = 1;
if (sd.ShowDialog() != DialogResult.OK)
return;
pictureBox.Image.Save(sd.FileName, System.Drawing.Imaging.ImageFormat.Bmp); // save to new bmp file
}
else if (e.Button == toolBarBtnTune)
{
if (capGraph != null)
DsUtils.ShowTunerPinDialog(capGraph, capFilter, this.Handle);
}
}
/// <summary> sample callback, NOT USED. </summary>
int ISampleGrabberCB.SampleCB(double SampleTime, IMediaSample pSample)
{
Trace.WriteLine("!!CB: ISampleGrabberCB.SampleCB");
return 0;
}
/// <summary> buffer callback, COULD BE FROM FOREIGN THREAD. </summary>
int ISampleGrabberCB.BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen)
{
if (captured || (savedArray == null))
{
Trace.WriteLine("!!CB: ISampleGrabberCB.BufferCB");
return 0;
}
captured = true;
bufferedSize = BufferLen;
Trace.WriteLine("!!CB: ISampleGrabberCB.BufferCB !GRAB! size = " + BufferLen.ToString());
if ((pBuffer != IntPtr.Zero) && (BufferLen > 1000) && (BufferLen <= savedArray.Length))
Marshal.Copy(pBuffer, savedArray, 0, BufferLen);
else
Trace.WriteLine(" !!!GRAB! failed ");
this.BeginInvoke(new CaptureDone(this.OnCaptureDone));
return 0;
}
/// <summary> capture event, triggered by buffer callback. </summary>
void OnCaptureDone()
{
Trace.WriteLine("!!DLG: OnCaptureDone");
try
{
toolBarBtnGrab.Enabled = true;
int hr;
if (sampGrabber == null)
return;
hr = sampGrabber.SetCallback(null, 0);
int w = videoInfoHeader.BmiHeader.Width;
int h = videoInfoHeader.BmiHeader.Height;
if (((w & 0x03) != 0) || (w < 32) || (w > 4096) || (h < 32) || (h > 4096))
return;
int stride = w * 3;
GCHandle handle = GCHandle.Alloc(savedArray, GCHandleType.Pinned);
int scan0 = (int)handle.AddrOfPinnedObject();
scan0 += (h - 1) * stride;
Bitmap b = new Bitmap(w, h, -stride, System.Drawing.Imaging.PixelFormat.Format24bppRgb, (IntPtr)scan0);
handle.Free();
savedArray = null;
Image old = pictureBox.Image;
pictureBox.Image = b;
if (old != null)
old.Dispose();
toolBarBtnSave.Enabled = true;
}
catch (Exception ee)
{
MessageBox.Show(this, "Could not grab picture\r\n" + ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
#endif
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -