基本信息
源码名称:Windows 7 下拍照源码下载(win7/win8下亲测通过)
源码大小:0.16M
文件格式:.zip
开发语言:C#
更新时间:2015-07-10
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
解决某些Windows 7下不能拍照问题。
public partial class frmCamera : Form, ISampleGrabberCB
{
#region 私有变量
/// <summary>
/// 保存抓拍的图片
/// </summary>
Image theImage = null;
/// <summary>
/// 需要重新抓拍的状态
/// </summary>
bool _reclap = false;
/// <summary>
/// 摄像头的状态
/// </summary>
bool _cameraIsStart = false;
/// <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>
/// control interface.
/// </summary>
private IMediaControl mediaCtrl;
/// <summary> event interface. </summary>
private IMediaEventEx mediaEvt;
/// <summary> video window interface. </summary>
private IVideoWindow videoWin;
/// <summary> grabber filter interface. </summary>
private IBaseFilter baseGrabFlt;
/// <summary> structure describing the bitmap to grab. </summary>
private VideoInfoHeader videoInfoHeader;
private bool captured = true;
private int bufferedSize;
/// <summary>
/// buffer for bitmap data.
/// </summary>
private byte[] savedArray;
/// <summary>
/// list of installed video devices.
/// </summary>
private ArrayList capDevices;
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;
/// <summary>
/// event when callback has finished (ISampleGrabberCB.BufferCB).
/// </summary>
private delegate void CaptureDone();
#if DEBUG
private int rotCookie = 0;
#endif
#endregion
#region 私有函数
/// <summary>
/// capture event, triggered by buffer callback.
/// </summary>
void OnCaptureDone()
{
Trace.WriteLine("!!DLG: OnCaptureDone");
try
{
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 = pbPicture.Image;
pbPicture.Image = b;
if (old != null)
old.Dispose();
}
catch (Exception ee)
{
MessageBox.Show(this, "Could not grab picture\r\n" ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
/// <summary>
/// start all the interfaces, graphs and preview window.
/// </summary>
bool StartupVideo(UCOMIMoniker mon)
{
int hr;
try
{
if (!CreateCaptureDevice(mon))
return false;
if (!GetInterfaces())
return false;
if (!SetupGraph())
return false;
if (!SetupVideoWindow())
return false;
#if DEBUG
DsROT.AddGraphToRot(graphBuilder, out rotCookie); // graphBuilder capGraph
#endif
hr = mediaCtrl.Run();
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
bool hasTuner = DsUtils.ShowTunerPinDialog(capGraph, capFilter, this.Handle);
return true;
}
catch (Exception ee)
{
MessageBox.Show(this, "Could not start video stream\r\n" ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop);
return false;
}
}
/// <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(pbCamera.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>
/// build the capture graph for grabber.
/// </summary>
bool SetupGraph()
{
int hr;
try
{
hr = capGraph.SetFiltergraph(graphBuilder);
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
hr = graphBuilder.AddFilter(capFilter, "Ds.NET Video Capture Device");
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
DsUtils.ShowCapPinDialog(capGraph, capFilter, this.Handle);
AMMediaType media = new AMMediaType();
media.majorType = MediaType.Video;
media.subType = MediaSubType.RGB24;
media.formatType = FormatType.VideoInfo; // ???
hr = sampGrabber.SetMediaType(media);
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
hr = graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber");
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
Guid cat = PinCategory.Preview;
Guid med = MediaType.Video;
hr = capGraph.RenderStream(ref cat, ref med, capFilter, null, null); // baseGrabFlt
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
cat = PinCategory.Capture;
med = MediaType.Video;
hr = capGraph.RenderStream(ref cat, ref med, capFilter, null, baseGrabFlt); // baseGrabFlt
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
media = new AMMediaType();
hr = sampGrabber.GetConnectedMediaType(media);
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
throw new NotSupportedException("Unknown Grabber Media Format");
videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));
Marshal.FreeCoTaskMem(media.formatPtr); media.formatPtr = IntPtr.Zero;
hr = sampGrabber.SetBufferSamples(false);
if (hr == 0)
hr = sampGrabber.SetOneShot(false);
if (hr == 0)
hr = sampGrabber.SetCallback(null, 0);
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
return true;
}
catch (Exception ee)
{
MessageBox.Show(this, "Could not setup graph\r\n" ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop);
return false;
}
}
/// <summary>
/// create the used COM components and get the interfaces.
/// </summary>
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>
/// 关闭摄像头 释放资源
/// </summary>
void stopCamera()
{
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;
}
baseGrabFlt = null;
if (sampGrabber != null)
Marshal.ReleaseComObject(sampGrabber); sampGrabber = 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>
/// resize preview video window to fill client area.
/// </summary>
void ResizeVideoWindow()
{
if (videoWin != null)
{
Rectangle rc = pbCamera.ClientRectangle;
videoWin.SetWindowPosition(0, 0, rc.Right, rc.Bottom);
}
}
/// <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>
/// 启动摄像头
/// </summary>
private void startCamera()
{
if (!DsUtils.IsCorrectDirectXVersion())//检查DirectX版本
{
MessageBox.Show(this, "DirectX 8.1 NOT installed!", "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop);
this.Close(); return;
}
//检查摄像头设备
if (!DsDev.GetDevicesOfCat(FilterCategory.VideoInputDevice, out capDevices))
{
MessageBox.Show(this, "No video capture devices found!", "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop);
this.Close(); return;
}
//如果只有一个摄像头设备,则直接指定设备;若不止一个,则弹出设备列表,选择一个
DsDevice dev = null;
if (capDevices.Count == 1)
dev = capDevices[0] as DsDevice;
else
{
frmCameraSelector selector = new frmCameraSelector(capDevices);
selector.ShowDialog(this);
dev = selector.SelectedDevice;
}
if (dev == null)
{
this.Close(); return;
}
//开始视频
if (!StartupVideo(dev.Mon))
this.Close();
}
#endregion
#region 接口实现
/// <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;
}
#endregion
#region 构造
public frmCamera()
{
InitializeComponent();
}
#endregion
#region 事件
/// <summary>
/// 重些 处理图像事件
/// </summary>
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_GRAPHNOTIFY)
{
if (mediaEvt != null)
OnGraphNotify();
return;
}
base.WndProc(ref m);
}
/// <summary>
/// 启动或关闭摄像头
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnStart_Click(object sender, EventArgs e)
{
if (!_cameraIsStart)
{
pbPicture.SendToBack();
startCamera();
_cameraIsStart = true;
btnStart.Text = "关闭摄像头";
btnClap.Text = "拍照";
}
else
{
stopCamera();
btnStart.Text = "启动摄像头";
btnClap.Text = "拍照";
_cameraIsStart = false;
_reclap = false;
}
}
/// <summary>
/// 拍照
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnClap_Click(object sender, EventArgs e)
{
if (_cameraIsStart == true)
{
if (_reclap == false)
{
Trace.WriteLine("!!BTN: toolBarBtnGrab");
if (savedArray == null)
{
int size = videoInfoHeader.BmiHeader.ImageSize;
if ((size < 1000) || (size > 16000000))
return;
savedArray = new byte[size 64000];
}
Image old = pbPicture.Image;
pbPicture.Image = null;
if (old != null)
old.Dispose();
captured = false;
int hr = sampGrabber.SetCallback(this, 1);
pbPicture.Image = theImage;
pbCamera.SendToBack();
_reclap = true;
btnClap.Text = "重拍";
}
else
{
pbPicture.SendToBack();
btnClap.Text = "拍照";
_reclap = false;
}
}
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new frmCamera());
}
}