2013-04-24 21 views
6

質問:ウェブカメラから画像をキャプチャするためのコードは次のとおりです。クリップボードを使用せずに画像をコピーする方法は?

私の問題は、この部分です:

SendMessage(hCaptureWnd, WM_CAP_COPY, 0, 0);     // copy it to the clipboard 

何それがないことはクリップボードに窓から画像をコピーして、そこからバイト配列を作成することです。

プログラムの実行中にクリップボードを使用しない限り機能します。
問題は、Visual StudioがWebアプリケーションのデバッグを開始するまでに何かをコピーしてクラッシュすることがあるので、これは自分自身では機能しません。

ここで私の質問:
クリップボードを使用せずに画像を取得するにはどうすればよいですか? さらに具体的には、hCaptureWndをSystem.Drawing.Imageに変換する方法は?


- 編集:
私は、「ファイルを作成せずに、私はバイト配列をしたい」と言って逃しました。
それはWebアプリケーションなので、ユーザはアプリケーションが下の(一時的なテストのためのファイルへの書き込み)ファイルシステムへの書き込みアクセス権を持つべきではありません実行されます...
- エンド編集:


/// <summary> 
/// Captures a frame from the webcam and returns the byte array associated 
/// with the captured image 
/// </summary> 
/// <param name="connectDelay">number of milliseconds to wait between connect 
/// and capture - necessary for some cameras that take a while to 'warm up'</param> 
/// <returns>byte array representing a bitmp or null (if error or no webcam)</returns> 
private static byte[] InternalCaptureToByteArray(int connectDelay = 500) 
{ 
    Clipboard.Clear();            // clear the clipboard 
    int hCaptureWnd = capCreateCaptureWindowA("ccWebCam", 0, 0, 0, // create the hidden capture window 
     350, 350, 0, 0); 
    SendMessage(hCaptureWnd, WM_CAP_CONNECT, 0, 0);     // send the connect message to it 
    Thread.Sleep(connectDelay);          // sleep the specified time 
    SendMessage(hCaptureWnd, WM_CAP_GET_FRAME, 0, 0);    // capture the frame 
    SendMessage(hCaptureWnd, WM_CAP_COPY, 0, 0);     // copy it to the clipboard 
    SendMessage(hCaptureWnd, WM_CAP_DISCONNECT, 0, 0);    // disconnect from the camera 
    Bitmap bitmap = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap); // copy into bitmap 

    if (bitmap == null) 
     return null; 

    using (MemoryStream stream = new MemoryStream()) 
    { 
     bitmap.Save(stream, ImageFormat.Bmp); // get bitmap bytes 
     return stream.ToArray(); 
    } // End Using stream 

} // End Function InternalCaptureToByteArray 

注(http://msdn.microsoft.com/en-us/library/windows/desktop/dd756879(v=vs.85).aspx):参考のため

HWND VFWAPI capCreateCaptureWindow(
    LPCTSTR lpszWindowName, 
    DWORD dwStyle, 
    int x, 
    int y, 
    int nWidth, 
    int nHeight, 
    HWND hWnd, 
    int nID 
); 


#define VFWAPI WINAPI 

typedef HANDLE HWND; 
typedef PVOID HANDLE; 
typedef void *PVOID; 

フルコード

using System; 
using System.IO; 
using System.Drawing; 
using System.Threading; 
using System.Windows.Forms; 
using System.Drawing.Imaging; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 


// http://www.creativecodedesign.com/node/66 
// http://www.barebonescoder.com/2012/01/finding-your-web-cam-with-c-directshow-net/ 
// http://www.codeproject.com/Articles/15219/WebCam-Fast-Image-Capture-Service-using-WIA 
// http://www.c-sharpcorner.com/uploadfile/yougerthen/integrate-the-web-webcam-functionality-using-C-Sharp-net-and-com-part-viii/ 
// http://forums.asp.net/t/1410057.aspx 


namespace cc.Utility 
{ 


    // bool isCaptured = ccWebCam.CaptureSTA("capture.jpg"); // Access to path C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0\capture.jpg" denied. 
    // byte[] captureBytes = ccWebCam.CaptureSTA(); 

    /// <summary> 
    /// Timur Kovalev (http://www.creativecodedesign.com): 
    /// This class provides a method of capturing a webcam image via avicap32.dll api. 
    /// </summary>  
    public static class ccWebCam 
    { 
     #region *** PInvoke Stuff - methods to interact with capture window *** 

     [DllImport("user32", EntryPoint = "SendMessage")] 
     private static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam); 

     [DllImport("avicap32.dll", EntryPoint = "capCreateCaptureWindowA")] 
     private static extern int capCreateCaptureWindowA(string lpszWindowName, int dwStyle, 
      int X, int Y, int nWidth, int nHeight, int hwndParent, int nID); 


     private const int WM_CAP_CONNECT = 1034; 
     private const int WM_CAP_DISCONNECT = 1035; 
     private const int WM_CAP_COPY = 1054; 
     private const int WM_CAP_GET_FRAME = 1084; 


     #endregion 


     private static object objWebCamThreadLock = new object(); 


     //CaptureToFile(@"D:\Stefan.Steiger\Documents\Visual Studio 2010\Projects\Post_Ipag\image3.jpg"): 
     public static bool Capture(string filePath, int connectDelay = 500) 
     { 
      lock (objWebCamThreadLock) 
      { 
       return cc.Utility.ccWebCam.InternalCaptureAsFileInThread(filePath, connectDelay); 
      } 
     } // End Treadsafe Function Capture 


     public static byte[] Capture(int connectDelay = 500) 
     { 
      lock (objWebCamThreadLock) 
      { 
       return InternalCaptureToByteArrayInThread(connectDelay); 
      } 
     } // End Treadsafe Function Capture 


     /// <summary> 
     /// Captures a frame from the webcam and returns the byte array associated 
     /// with the captured image. The image is also stored in a file 
     /// </summary> 
     /// <param name="filePath">path the file wher ethe image will be saved</param> 
     /// <param name="connectDelay">number of milliseconds to wait between connect 
     /// and capture - necessary for some cameras that take a while to 'warm up'</param> 
     /// <returns>true on success, false on failure</returns> 
     private static bool InternalCaptureAsFileInThread(string filePath, int connectDelay = 500) 
     { 
      bool success = false; 
      Thread catureThread = new Thread(() => 
      { 
       success = InternalCaptureAsFile(filePath, connectDelay); 
      }); 
      catureThread.SetApartmentState(ApartmentState.STA); 
      catureThread.Start(); 
      catureThread.Join(); 
      return success; 
     } // End Function InternalCaptureAsFileInThread 


     /// <summary> 
     /// Captures a frame from the webcam and returns the byte array associated 
     /// with the captured image. The image is also stored in a file 
     /// </summary> 
     /// <param name="filePath">path the file wher ethe image will be saved</param> 
     /// <param name="connectDelay">number of milliseconds to wait between connect 
     /// and capture - necessary for some cameras that take a while to 'warm up'</param> 
     /// <returns>true on success, false on failure</returns> 
     private static bool InternalCaptureAsFile(string filePath, int connectDelay = 500) 
     { 
      byte[] capture = ccWebCam.InternalCaptureToByteArray(connectDelay); 
      if (capture != null) 
      { 
       // Access to path C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0\image1.jpg" denied. 
       File.WriteAllBytes(filePath, capture); 
       return true; 
      } 
      return false; 
     } // End Function InternalCaptureAsFile 


     /// <summary> 
     /// Captures a frame from the webcam and returns the byte array associated 
     /// with the captured image. Runs in a newly-created STA thread which is 
     /// required for this method of capture 
     /// </summary> 
     /// <param name="connectDelay">number of milliseconds to wait between connect 
     /// and capture - necessary for some cameras that take a while to 'warm up'</param> 
     /// <returns>byte array representing a bitmp or null (if error or no webcam)</returns> 
     private static byte[] InternalCaptureToByteArrayInThread(int connectDelay = 500) 
     { 
      byte[] bytes = null; 
      Thread catureThread = new Thread(() => 
      { 
       bytes = InternalCaptureToByteArray(connectDelay); 
      }); 
      catureThread.SetApartmentState(ApartmentState.STA); 
      catureThread.Start(); 
      catureThread.Join(); 
      return bytes; 
     } // End Function InternalCaptureToByteArrayInThread 


     /// <summary> 
     /// Captures a frame from the webcam and returns the byte array associated 
     /// with the captured image 
     /// </summary> 
     /// <param name="connectDelay">number of milliseconds to wait between connect 
     /// and capture - necessary for some cameras that take a while to 'warm up'</param> 
     /// <returns>byte array representing a bitmp or null (if error or no webcam)</returns> 
     private static byte[] InternalCaptureToByteArray(int connectDelay = 500) 
     { 
      Clipboard.Clear();            // clear the clipboard 
      int hCaptureWnd = capCreateCaptureWindowA("ccWebCam", 0, 0, 0, // create the hidden capture window 
       350, 350, 0, 0); 
      SendMessage(hCaptureWnd, WM_CAP_CONNECT, 0, 0);     // send the connect message to it 
      Thread.Sleep(connectDelay);          // sleep the specified time 
      SendMessage(hCaptureWnd, WM_CAP_GET_FRAME, 0, 0);    // capture the frame 
      SendMessage(hCaptureWnd, WM_CAP_COPY, 0, 0);     // copy it to the clipboard 
      SendMessage(hCaptureWnd, WM_CAP_DISCONNECT, 0, 0);    // disconnect from the camera 
      Bitmap bitmap = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap); // copy into bitmap 

      if (bitmap == null) 
       return null; 

      using (MemoryStream stream = new MemoryStream()) 
      { 
       bitmap.Save(stream, ImageFormat.Bmp); // get bitmap bytes 
       return stream.ToArray(); 
      } // End Using stream 

     } // End Function InternalCaptureToByteArray 


    } 


} 

私はこのようにしようとしたが、それが唯一の黒画像を取得...そして

[DllImport("user32.dll")] 
    static extern IntPtr GetWindowDC(IntPtr hWnd); 

    [DllImport("gdi32.dll", SetLastError = true)] 
    static extern IntPtr CreateCompatibleDC(IntPtr hdc); 

    enum TernaryRasterOperations : uint 
    { 
     /// <summary>dest = source</summary> 
     SRCCOPY = 0x00CC0020, 
     /// <summary>dest = source OR dest</summary> 
     SRCPAINT = 0x00EE0086, 
     /// <summary>dest = source AND dest</summary> 
     SRCAND = 0x008800C6, 
     /// <summary>dest = source XOR dest</summary> 
     SRCINVERT = 0x00660046, 
     /// <summary>dest = source AND (NOT dest)</summary> 
     SRCERASE = 0x00440328, 
     /// <summary>dest = (NOT source)</summary> 
     NOTSRCCOPY = 0x00330008, 
     /// <summary>dest = (NOT src) AND (NOT dest)</summary> 
     NOTSRCERASE = 0x001100A6, 
     /// <summary>dest = (source AND pattern)</summary> 
     MERGECOPY = 0x00C000CA, 
     /// <summary>dest = (NOT source) OR dest</summary> 
     MERGEPAINT = 0x00BB0226, 
     /// <summary>dest = pattern</summary> 
     PATCOPY = 0x00F00021, 
     /// <summary>dest = DPSnoo</summary> 
     PATPAINT = 0x00FB0A09, 
     /// <summary>dest = pattern XOR dest</summary> 
     PATINVERT = 0x005A0049, 
     /// <summary>dest = (NOT dest)</summary> 
     DSTINVERT = 0x00550009, 
     /// <summary>dest = BLACK</summary> 
     BLACKNESS = 0x00000042, 
     /// <summary>dest = WHITE</summary> 
     WHITENESS = 0x00FF0062, 
     /// <summary> 
     /// Capture window as seen on screen. This includes layered windows 
     /// such as WPF windows with AllowsTransparency="true" 
     /// </summary> 
     CAPTUREBLT = 0x40000000 
    } 

    [DllImport("gdi32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop); 

    [DllImport("gdi32.dll")] 
    static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); 

    [DllImport("gdi32.dll", ExactSpelling = true, PreserveSig = true, SetLastError = true)] 
    static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); 

    [DllImport("gdi32.dll")] 
    static extern bool DeleteDC(IntPtr hdc); 

    [DllImport("user32.dll")] 
    static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC); 

    [DllImport("gdi32.dll")] 
    static extern bool DeleteObject(IntPtr hObject); 


    public static void ScreenshotWindow(IntPtr windowHandle) 
    { 
     Rect Rect = new Rect(); 

     GetWindowRect(windowHandle, ref Rect); 
     int width = Rect.Right - Rect.Left; 
     int height = Rect.Bottom - Rect.Top; 

     IntPtr windowDeviceContext = GetWindowDC(windowHandle); 
     IntPtr destDeviceContext = CreateCompatibleDC(windowDeviceContext); 
     IntPtr bitmapHandle = CreateCompatibleBitmap(windowDeviceContext, width, height); 
     IntPtr oldObject = SelectObject(destDeviceContext, bitmapHandle); 

     BitBlt(destDeviceContext, 0, 0, width, height, windowDeviceContext, 0, 0, TernaryRasterOperations.CAPTUREBLT | TernaryRasterOperations.SRCCOPY); 
     SelectObject(destDeviceContext, oldObject); 

     DeleteDC(destDeviceContext); 
     ReleaseDC(windowHandle, destDeviceContext); 


     Image screenshot = Image.FromHbitmap(bitmapHandle); 
     DeleteObject(bitmapHandle); 

     screenshot.Save("d:\\temp\\mywebcamimage.png", System.Drawing.Imaging.ImageFormat.Png); 

     /* 
     // TODO - Remove above save when it works 
     using (MemoryStream stream = new MemoryStream()) 
     { 
      screenshot.Save(stream, System.Drawing.Imaging.ImageFormat.Png); 
      return stream.ToArray(); 
     } 
     */ 
    } 

そしてこのSendMessage(hCaptureWnd, WM_CAP_GET_FRAME, 0, 0);

ScreenshotWindow(new IntPtr(hCaptureWnd)); 
+0

これらの追加のものと

SendMessage(hCaptureWnd, WM_CAP_SET_CALLBACK_FRAME, 0, capVideoStreamCallback); SendMessage(hCaptureWnd, WM_CAP_GRAB_FRAME, 0, 0); // capture the frame 

あなただけ... * *画像をクリップボードにコピーしないで、代わりにバイト配列に直接変換しない理由を私は理解していません。このロジックを含む 'WM_CAP_COPY'メッセージハンドラですか?このメッセージを提供するライブラリは何ですか?その行動を無効にすることはできますか? –

+0

@Cody Grey:そのライブラリはWindowsです! WinAPI!そして、いいえ、私は窓を変更することはできません、私はソースコードを持っていません(私は分解してパッチを当てることはできませんでしたが、ここでは間違ったアプローチです);そしてあなたの質問に答えるために:ちなみに質問であるhCaptureWndから画像を作成するには... –

+0

うーん、なぜドキュメントが見つかりませんか?私はここで私のリーグを離れていると思う。聞いたことがない。 –

答えて

1

ローマR.の答えのビル:

の道徳の細かい点を使用すると、コールバックフレームを登録する必要があるということです、そしてgrabframeを呼び出し、 とあなたは直接Cスタイルの文字をキャストできません[]また、capCreateCaptureWindowAに設定されているものとは無関係に、画像サイズは640x480であり、lpDataはUIntPtrではなくIntPtrである必要があることをMarshal.Copy UIntPtrのオーバーロードがなく、WriteBitmapFileを使用すると、安全でないコードやビットマップファイルのヘッダーを使用せずにビットマップにビットマップデータを書き込むことができます。また、Marshal.Copyを書き込んだ人は、 intではありません。

また、何らかの理由で180のoldDegreesイメージを回転する必要があります。
また、WM定数を正しい名前に変更しました。

// http://msdn.microsoft.com/en-us/library/windows/desktop/dd757688(v=vs.85).aspx 
    [StructLayout(LayoutKind.Sequential)] 
    private struct VIDEOHDR 
    { 
     // http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx 


     // typedef unsigned char BYTE; 
     // typedef BYTE far *LPBYTE; 
     // unsigned char* lpData 


     //public byte[] lpData; // LPBYTE lpData; // Aaargh, invalid cast, not a .NET byte array... 
     public IntPtr lpData; // LPBYTE lpData; 
     public UInt32 dwBufferLength; // DWORD  dwBufferLength; 
     public UInt32 dwBytesUsed; // DWORD  dwBytesUsed; 
     public UInt32 dwTimeCaptured; // DWORD  dwTimeCaptured; 


     // typedef ULONG_PTR DWORD_PTR; 
     // #if defined(_WIN64) 
     // typedef unsigned __int64 ULONG_PTR; 
     // #else 
     // typedef unsigned long ULONG_PTR; 
     // #endif 
     public IntPtr dwUser; // DWORD_PTR dwUser; 
     public UInt32 dwFlags; // DWORD  dwFlags; 

     [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4)] 
     public System.UIntPtr[] dwReserved; // DWORD_PTR dwReserved[4]; 

     // Does not make a difference 
     //public System.UIntPtr[] dwReserved = new System.UIntPtr[4]; // DWORD_PTR dwReserved[4]; 
    } 




    private delegate System.IntPtr capVideoStreamCallback_t(System.UIntPtr hWnd, ref VIDEOHDR lpVHdr); 
    [DllImport("user32", EntryPoint = "SendMessage")] 
    private static extern int SendMessage(int hWnd, uint Msg, int wParam, capVideoStreamCallback_t routine); 




    // http://eris.liralab.it/yarpdoc/vfw__extra__from__wine_8h.html 
    private const int WM_USER = 0x0400; // 1024 
    private const int WM_CAP_START = WM_USER; 
    private const int WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10; 
    private const int WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11; 

    private const int WM_CAP_FILE_SAVEDIB = WM_CAP_START + 25; 
    private const int WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START + 5; 
    private const int WM_CAP_GRAB_FRAME = WM_CAP_START + 60; 
    private const int WM_CAP_EDIT_COPY = WM_CAP_START + 30; 




    // http://lists.ximian.com/pipermail/mono-devel-list/2011-March/037272.html 

    private static byte[] baSplendidIsolation; 


    private static System.IntPtr capVideoStreamCallback(System.UIntPtr hWnd, ref VIDEOHDR lpVHdr) 
    { 
     //System.Windows.Forms.MessageBox.Show("hello"); 
     //System.Windows.Forms.MessageBox.Show(lpVHdr.dwBufferLength.ToString() + " " + lpVHdr.dwBytesUsed.ToString()); 
     byte[] _imageTemp = new byte[lpVHdr.dwBufferLength]; 
     Marshal.Copy(lpVHdr.lpData, _imageTemp, 0, (int) lpVHdr.dwBufferLength); 
     //System.IO.File.WriteAllBytes(@"d:\temp\mycbfile.bmp", _imageTemp); // AAaaarg, it's raw bitmap data... 

     // http://stackoverflow.com/questions/742236/how-to-create-a-bmp-file-from-byte-in-c-sharp 
     // http://stackoverflow.com/questions/2654480/writing-bmp-image-in-pure-c-c-without-other-libraries 

     // Tsssss... 350 x 350 was the expected setting, but never mind... 
     // fortunately alex told me about WM_CAP_FILE_SAVEDIB, so I could compare to the direct output 
     int width = 640; 
     int height = 480; 
     int stride = width*3; 

     baSplendidIsolation = null; 
     baSplendidIsolation = WriteBitmapFile(@"d:\temp\mycbfilecc.bmp", width, height, _imageTemp); 

     /* 
     unsafe 
     { 
      fixed (byte* ptr = _imageTemp) 
      { 
       using (Bitmap image = new Bitmap(width, height, stride, PixelFormat.Format24bppRgb, new IntPtr(ptr))) 
       { 
        image.Save(@"d:\temp\mycbfile2.bmp"); 
       } 
      } 
     } 
     */ 

     //var hdr = (Elf32_Phdr)Marshal.PtrToStructure(ptr, typeof(Elf32_Phdr)); 
     return System.IntPtr.Zero; 
    } 


    private static byte[] WriteBitmapFile(string filename, int width, int height, byte[] imageData) 
    { 
     using (var stream = new MemoryStream(imageData)) 
     using (var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb)) 
     { 
      BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0,bmp.Width, bmp.Height) 
               ,ImageLockMode.WriteOnly 
               ,bmp.PixelFormat 
      ); 

      Marshal.Copy(imageData, 0, bmpData.Scan0, imageData.Length); 

      bmp.UnlockBits(bmpData); 


      if (bmp == null) 
       return null; 

      bmp.RotateFlip(RotateFlipType.Rotate180FlipNone); 
      bmp.Save(filename); // For testing only 

      using (MemoryStream ms = new MemoryStream()) 
      { 
       bmp.Save(ms, ImageFormat.Png); // get bitmap bytes 
       return ms.ToArray(); 
      } // End Using stream 

     } 

    } // End Function WriteBitmapFile 


    /// <summary> 
    /// Captures a frame from the webcam and returns the byte array associated 
    /// with the captured image 
    /// </summary> 
    /// <param name="connectDelay">number of milliseconds to wait between connect 
    /// and capture - necessary for some cameras that take a while to 'warm up'</param> 
    /// <returns>byte array representing a bitmp or null (if error or no webcam)</returns> 
    private static byte[] InternalCaptureToByteArray(int connectDelay = 500) 
    { 
     Clipboard.Clear(); 
     int hCaptureWnd = capCreateCaptureWindowA("ccWebCam", 0, 0, 0, 
      350, 350, 0, 0); // create the hidden capture window 
     SendMessage(hCaptureWnd, WM_CAP_DRIVER_CONNECT, 0, 0); // send the connect message to it 
     //SendMessage(hCaptureWnd, WM_CAP_DRIVER_CONNECT, i, 0); // i device number retval != 0 --> valid device_id 

     Thread.Sleep(connectDelay);          // sleep the specified time 
     SendMessage(hCaptureWnd, WM_CAP_SET_CALLBACK_FRAME, 0, capVideoStreamCallback); 
     SendMessage(hCaptureWnd, WM_CAP_GRAB_FRAME, 0, 0);    // capture the frame 

     //SendMessage(hCaptureWnd, WM_CAP_FILE_SAVEDIB, 0, "d:\\temp\\testmywebcamimage.bmp"); 
     //ScreenshotWindow(new IntPtr(hCaptureWnd)); 

     //SendMessage(hCaptureWnd, WM_CAP_EDIT_COPY, 0, 0); // copy it to the clipboard 


     // using (Graphics g2 = Graphics.FromHwnd(new IntPtr(hCaptureWnd))) 

     SendMessage(hCaptureWnd, WM_CAP_DRIVER_DISCONNECT, 0, 0);    // disconnect from the camera 

     return baSplendidIsolation; 

     /* 
     Bitmap bitmap = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap); // copy into bitmap 

     if (bitmap == null) 
      return null; 

     using (MemoryStream stream = new MemoryStream()) 
     { 
      bitmap.Save(stream, ImageFormat.Bmp); // get bitmap bytes 
      return stream.ToArray(); 
     } // End Using stream 
     */ 
    } // End Function InternalCaptureToByteArray 
+0

コードで使用したWM_CAP_GRAB_FRAME&WM_CAP_SET_CALLBACK_FRAMEの16進値は?私は以下のような他のものを使用しています public const uint WM_CAP_DRIVER_CONNECT = 0x40a; public const uint WM_CAP_DRIVER_DISCONNECT = 0x40b; public const uint WM_CAP_EDIT_COPY = 0x41e; public const uint WM_CAP_SET_PREVIEW = 0x432; public const uint WM_CAP_SET_OVERLAY = 0x433; public const uint WM_CAP_SET_PREVIEWRATE = 0x434; –

3

後あなたは具体的には、異なるメッセージを送信する必要がありますWM_CAP_FILE_SAVEDIB、ディスク上のファイルにデータを保存します。その後、それをさらに処理するためにBitmapオブジェクトにロードすることができます(私は組み込みカムtoバイト[]機能を認識していません)。

[DllImport("user32", EntryPoint = "SendMessage")] 
private static extern int SendMessage(
    int hWnd, uint Msg, int wParam, string strFileName); 

private const int WM_USER = 0x0400; 
private const int WM_CAP_START = WM_USER; 
private const int WM_CAP_FILE_SAVEDIB = WM_CAP_START + 25; 

//before 
SendMessage(hCaptureWnd, WM_CAP_COPY, 0, 0); 

//after 
string tempFile = Server.MapPath("~/App_Data/tempCap.bmp"); 
SendMessage(hCaptureWnd, WM_CAP_FILE_SAVEDIB, 0, tempFile); //create tempfile 
Bitmap bitmap = new Bitmap(tempFile); //read tempfile 
using (MemoryStream stream = new MemoryStream()) 
{ 
    bitmap.Save(stream, ImageFormat.Bmp); 
    return stream.ToArray(); 
} 
+0

OK、これはファイルのためのもので、バイト配列(ファイルをロードせずに)は何ですか? –

+0

私はdllがまっすぐなcam-to-byte []メッセージを提供しているとは思わない – Alex

+0

もちろん、WinAPIはhCaptureWndをビットマップに変換する方法を提供します。 –

6

WM_CAP_GET_FRAMEのようなものはありません。メッセージの正しい名前はWM_CAP_GRAB_FRAMEで、MSDNに記載されています。それは何

である:

WM_CAP_GRAB_FRAMEメッセージがキャプチャドライバから単一のフレーム を取得し、表示します。キャプチャ後、オーバーレイとプレビューは が無効になります。このメッセージを明示的に送信することも、 capGrabFrameマクロを使用して送信することもできます。

実際のデータを取得するには、frame callback as described further on MSDNを使用する必要があります。コールバックは画像​​のバイトを取得します。このバイトはファイルに書き込んだり、クリップボードに転送しなくても何らかの処理に使用することができます。

...ストリーミングキャプチャで使用されるコールバック関数で、オプションで キャプチャしたビデオのフレームを処理します。 capVideoStreamCallbackという名前は、アプリケーション提供の関数名のプレースホルダである です。

[そしてあなたには...]キャプチャされたフレームに関する情報を含むVIDEOHDR構造体へのポインタ。

また、このAPIはビデオキャプチャにとって不利な選択です。あまりにも古い、あまりにも限られた。

関連する問題