2013-08-21 54 views
0

我寫了一個c#程序,使用.net框架2.0攝像頭拍照。我試圖使用avicap32.dll來調用攝像頭。只有一次調用avicap32 c#

問題是我可以打電話給我的網絡攝像頭一次,如果我斷開網絡攝像頭並通過一些按鈕重新啓動它,那麼圖片箱將顯示一張黑色照片,並且無法再次調用網絡攝像頭。如果我再次重新啓動程序,它將在圖片框中保持黑色。只有當我重新啓動我的電腦。 W.T.F.任何人都可以解決這個問題?

我把源代碼放在下面。試着弄清楚發生了什麼事。另一個瑕疵是圖片框中的照片不能設置圖片的中心。

這裏的Form1.cs的

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.Threading; 

namespace AutoCam 
{ 
    public partial class form1 : Form 
    { 

     public form1() 
     { 
      InitializeComponent(); 
     } 
     Camera camera; 

     #region InitializeComponent 

     #region btn_openCamera #endregion 
     private void button1_Click(object sender, EventArgs e) 
     { 

      this.btn_openCamera.Enabled = false; 
      this.btn_closeCam.Enabled = true; 
      this.btn_cameraPic.Enabled = true; 
      camera = new Camera(this.pic_camera.Handle, this.pic_camera.Width, this.pic_camera.Height); 
      camera.StartWebCam(); 
     } 
     #endregion 

     #region btn_closeCam_Click 
     private void btn_closeCam_Click(object sender, EventArgs e) 
     { 
      this.btn_openCamera.Enabled = true; 
      this.btn_closeCam.Enabled = false; 
      this.btn_cameraPic.Enabled = false; 
      camera.CloseWebcam(); 
     } 
     #endregion 

     #region btn_cameraPic_Click 
     private void btn_cameraPic_Click(object sender, EventArgs e) 
     { 
      camera.GrabImage(this.pic_camera.Handle, "guying.bmp"); 
     } 
     #endregion 

     private void quit_Click(object sender, EventArgs e) 
     { 
      this.Close(); 
     } 
    } 
} 

這裏的camera.cs

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Threading; 
using System.Runtime.InteropServices; 
using System.IO; 
using System.Windows; 

namespace AutoCam 
{ 

    class Camera 
    { 
    private IntPtr lwndC; 
     private IntPtr mControlPtr; 
     private int mWidth; 
     private int mHeight; 

     public Camera(IntPtr handel, int width, int height) 
     { 
      mControlPtr = handel; //handle of video dom 
      mWidth = width; //video width 
      mHeight = height; //video height 
     } 

     public void StartWebCam() 
     { 
      byte[] lpszName = new byte[100]; 
      byte[] lpszVer = new byte[100]; 
      CameraAPI.capGetDriverDescriptionA(0, lpszName,100, lpszVer, 0); 
      this.lwndC = CameraAPI.capCreateCaptureWindowA(lpszName, CameraAPI.WS_CHILD | CameraAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0); 
      if (CameraAPI.SendMessage(lwndC, CameraAPI.WM_CAP_DRIVER_CONNECT, 0, 0)) 
      { 
       CameraAPI.SendMessage(lwndC, CameraAPI.WM_CAP_SET_PREVIEWRATE, 100, 0); 
       CameraAPI.SendMessage(lwndC, CameraAPI.WM_CAP_SET_PREVIEW, true, 0); 
      } 
     } 

     public void CloseWebcam() 
     { 
      CameraAPI.SendMessage(lwndC, CameraAPI.WM_CAP_DRIVER_DISCONNECT, 0, 0); 
     } 

     public void GrabImage(IntPtr hWndC, string path) 
     { 
      IntPtr hBmp = Marshal.StringToHGlobalAnsi(path); 
      CameraAPI.SendMessage(lwndC, CameraAPI.WM_CAP_SAVEDIB, 0, hBmp.ToInt32()); 
     } 

    } 

} 

這裏的cameraAPI.cs

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.Threading; 

namespace AutoCam 
{ 
    class CameraAPI 
    { 
     [DllImport("avicap32.dll")] 
     public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID); 
     [DllImport("avicap32.dll")] 
     public static extern bool capGetDriverDescriptionA(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer); 
     [DllImport("User32.dll")] 
     public static extern bool SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam); 
     [DllImport("User32.dll")] 
     public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, int lParam); 

     public const int WM_USER = 0x400; 
     public const int WS_CHILD = 0x40000000; 
     public const int WS_VISIBLE = 0x10000000; 
     public const int SWP_NOMOVE = 0x2; 
     public const int SWP_NOZORDER = 0x4; 
     public const int WM_CAP_DRIVER_CONNECT = WM_USER + 10; 
     public const int WM_CAP_DRIVER_DISCONNECT = WM_USER +11; 
     public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER +5; 
     public const int WM_CAP_SET_PREVIEW = WM_USER+50; 
     public const int WM_CAP_SET_PREVIEWFORMAT = WM_USER + 45; 
     public const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52; 
     public const int WM_CAP_START = WM_USER; 
     public const int WM_CAP_SAVEDIB = WM_CAP_START + 25; 

    } 
} 

回答

0

您可以參考這個blog,並修改碼。我已經嘗試了代碼,它運行良好。 點擊停止:

  bStopped = true; 
      this.timer.Stop(); 

      Application.DoEvents(); 

      SendMessage(m_CapHwnd, WM_CAP_DISCONNECT, 0, 0); 

      CloseClipboard(); 

點擊開始:

 stop(); 

     m_CapHwnd = capCreateCaptureWindowA("WebCap", 0, 0, 0, m_Width, m_Height, this.Handle.ToInt32(), 0); 

     Application.DoEvents(); 

     SendMessage(m_CapHwnd, WM_CAP_CONNECT, 0, 0); 

     this.timer.Interval = 1; 

     bStopped = false; 
     this.timer.Start(); 

計時器回調:

 this.timer.Stop(); 

     SendMessage(m_CapHwnd, WM_CAP_GT_FRAME, 0, 0); 

     SendMessage(m_CapHwnd, WM_CAP_COPY, 0, 0); 

     OpenClipboard(m_CapHwnd); 

     CloseClipboard(); 

     IDataObject dataObj = Clipboard.GetDataObject(); 
     Image img = (System.Drawing.Bitmap)dataObj.GetData(DataFormats.Bitmap); 
     //img.Save("e:\\test_" + DateTime.UtcNow.Ticks + ".jpg"); 
     pictureBox.Image = img; 

     pictureBox.Refresh(); 

     Application.DoEvents(); 

     if (!bStopped) 
     { 
      this.timer.Start(); 
     }