none
C#利用 API 存取Webcam 存取圖片問題 RRS feed

  • 問題

  • 我主要以C#語法為開發利用API函數來開啟多台攝影機並將它做影像相關處理,可是目前遇到一些瓶頸,請問各位先知能否能幫我解惑。

    請問:

          要存取Picturebox內的攝影機影像,我曾經利用 webCamPictureBox 的範例並以 this.webCamPictureBox1.Image.Save("C:\\image\\ok.bmp"); 成功將影像存取成圖檔到指定路徑。

          但為了開啟多台攝影機,所以我就改換以API函數來開啟攝影機,可是當我使用 PictureBox1.Image.Save("C:\\image\\ok.bmp");時他卻會出現NullReferenceException未處理,請問該如何才可以將它存檔。

    題外:

                    Form1.SendMessage(this.mCapHwnd, 0x41e, 0, 0);
                    IDataObject obj1 = Clipboard.GetDataObject();
                    if (obj1.GetDataPresent(typeof(Bitmap)))
                    {
                        Image image1 = (Image)obj1.GetData(typeof(Bitmap));
                        SaveFileDialog SaveFileDialog1 = new SaveFileDialog();
                        SaveFileDialog1.FileName = DateTime.Now.ToString("yyyyMMddhhmmss");
                        SaveFileDialog1.Filter = "Image Files(*.JPG;*.GIF)|*.JPG;*.GIF|All files (*.*)|*.*";
                        if (SaveFileDialog1.ShowDialog() == DialogResult.OK)
                        {
                            image1.Save(SaveFileDialog1.FileName, ImageFormat.Bmp);
                        }
                    }

    我利用FileDialog 是可以成功存檔,可是他不是我要的方式,我想直接能自動存在我指定的地方,後來我有找到一篇文章他寫到

    C#中透過Windows API(AVICap32)截取WebCam畫面

    const int WM_CAP_DRIVER_CONNECT = 0x40a;
    const int WM_CAP_DRIVER_DISCONNECT = 0x40b;
    const int WM_CAP_EDIT_COPY = 0x41e;
    const int WS_CHILD = 0x40000000;
    const int WS_VISIBLE = 0x10000000;
    const int WM_CAP_GRAB_FRAME = 0x43c;
    [DllImport("avicap32")]
    static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
    [DllImport("user32")]
    static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.AsAny)] object lParam);
    [DllImport("user32")]
    static extern bool DestroyWindow(IntPtr hwnd);
    byte[] baDeviceName = new byte[1];
    //建立設備的Handle
    IntPtrintDeviceHandle = capCreateCaptureWindowA(baDeviceName, WS_VISIBLE | WS_CHILD, 0, 0, 0, 0, this.Handle, 0);
    SendMessage(intDeviceHandle, WM_CAP_DRIVER_CONNECT, 0, 0); //連接設備
    if (SendMessage(intDeviceHandle, WM_CAP_GRAB_FRAME, 0, 0) > 0) //如果有截取到畫面
    {
    if (SendMessage(intDeviceHandle, WM_CAP_EDIT_COPY, 0, 0) > 0) //如果有Copy到剪貼簿
    {
     IDataObject MyClipboardObject = Clipboard.GetDataObject();//取得剪貼簿物件
     if (MyClipboardObject.GetDataPresent(typeof(Bitmap))) //看看是不是點陣圖
        Bitmap MyBitmap = (Bitmap)MyClipboardObject.GetData(typeof(Bitmap)); //取出點陣圖
    }

    }

    他所表達就是我想要的,可是我看不太懂他的意思,不知該從何用起,還煩請各位能幫我解惑。

    謝謝您。



    2013年4月10日 下午 04:57

解答

  • 試試看

     Form1.SendMessage(this.mCapHwnd, 0x41e, 0, 0);
     IDataObject obj1 = Clipboard.GetDataObject();
     if (obj1.GetDataPresent(typeof(Bitmap)))
     {
        Image image1 = (Image)obj1.GetData(typeof(Bitmap));
        image1.Save("C:\\image\\ok.bmp", ImageFormat.Bmp);
     }


    以下為簽名檔,如果你愛拉椅子坐那就是你的問題。
    先查MSDN文件庫
    再用GOOGLE搜尋
    才到論壇來發問

    這是論壇不是技術支援中心
    沒有人得無償解答你的問題

    在標題或文章註明很急
    不會增加網友回覆速度
    微軟實戰課程日

    • 已標示為解答 脆脆 2013年4月11日 上午 08:59
    2013年4月11日 上午 01:26

所有回覆

  • 我的印象中,你用API的方式將WEB CAM的畫面畫到畫面上的時候,假設你是用PictureBox,他也不會去動到Image的屬性的,只是提供一塊指定區域讓API去畫圖(你用panel同樣可以畫web cam的畫面上去),所以直接用Image.Save是存不到東西的;另外一部分我印象中用API的方式一次也只能帶出一支CAM,如果要同時帶兩支出來會遇到困難的,建議你試試看DirectShow.Net

    http://directshownet.sourceforge.net/

    我之前之用這個,同時抓兩隻web cam的live畫面,存檔也是OK的;參考看看


    請注意討論區相關規則,良好的討論環境需要大家共同努力、遵守

    2013年4月11日 上午 01:25
  • 試試看

     Form1.SendMessage(this.mCapHwnd, 0x41e, 0, 0);
     IDataObject obj1 = Clipboard.GetDataObject();
     if (obj1.GetDataPresent(typeof(Bitmap)))
     {
        Image image1 = (Image)obj1.GetData(typeof(Bitmap));
        image1.Save("C:\\image\\ok.bmp", ImageFormat.Bmp);
     }


    以下為簽名檔,如果你愛拉椅子坐那就是你的問題。
    先查MSDN文件庫
    再用GOOGLE搜尋
    才到論壇來發問

    這是論壇不是技術支援中心
    沒有人得無償解答你的問題

    在標題或文章註明很急
    不會增加網友回覆速度
    微軟實戰課程日

    • 已標示為解答 脆脆 2013年4月11日 上午 08:59
    2013年4月11日 上午 01:26
  • Hi,

    稍微瞄了一下~

    我不確定這樣的方式確定可行!?

    從你的code看來並沒有啟動多個webcam的地方

    而且就算啟動了多個webcam

    WM_CAP_EDIT_COPY把frame存入剪貼簿

    同時間啟動多個webcam但是都存在同一個剪貼簿

    如果不動些手腳應該是不能分辨這張圖是來自哪個webcam的...


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    2013年4月11日 上午 06:39
  • 謝謝 bauann 的用心答覆,點出我所疑惑的問題點,謝謝您。

    謝謝 Alex_Lee 的答覆,您所提供的程式,可以直接存取到我想要的地方,解惑了我多天的盲點,非常的感謝。

    謝謝 蹂躪 的答覆,我將兩個畫面分別存以不同的黨名,在同一個資料夾裡,方法是可行的,謝謝您的用心答覆。
    • 已編輯 脆脆 2013年4月11日 上午 09:16
    2013年4月11日 上午 08:59