2014-07-04 2 views
0

간단한 Windows에서 웹캠 스트림을 렌더링하는 것이 목표 인 .NET을 사용하는 간단한 OpenCV 응용 프로그램을 작성하고 있습니다. 여기 Marshal.Copy() 메서드를 사용한 액세스 위반 예외

내가이 작업을 수행하는 데 사용하는 코드입니다 :

private static BitmapSource ToBitmapSource(IImage image) 
{ 
    using (System.Drawing.Bitmap source = image.Bitmap) 
    { 
     IntPtr ptr = source.GetHbitmap(); 
     BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
      ptr, 
      IntPtr.Zero, 
      Int32Rect.Empty, 
      System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); 
     DeleteObject(ptr); 
     return bs; 
    } 
} 

private void CameraShow() 
{ 
    ImageViewer viewer = new Emgu.CV.UI.ImageViewer(); //create an image viewer 
    Capture capture = new Capture(); //create a camera captue 

    this.isCamOff = false; 
    while (this.CamStat != eCamRun.CamStop) 
    { 
     Thread.Sleep(60); 
     viewer.Image = capture.QueryFrame(); //draw the image obtained from camera 
     System.Windows.Application.Current.Dispatcher.Invoke(
      DispatcherPriority.Normal, 
      (ThreadStart)delegate 
     { 
      this.ImageStream.Source = ToBitmapSource(viewer.Image); //BitmapSource 
     }); 
    } 

    viewer.Dispose(); 
    capture.Dispose(); 
    this.isCamOff = true; 
    Thread.CurrentThread.Interrupt(); 
} 

을하지만 지금은 콘솔에서 System.Drawing.Bitmap 개체에 포함 된 픽셀 버퍼의 내용을 표시 할 (I *이 공백을 알고 네이티브 형식은 IntPtr 변수에 Bitmap 개체에 포함됩니다. 그래서 (에 '안전하지 않은'상황에) 내가 다음 코드 줄을 작성해야하는 IntPtr입니다 변수를 복구 할 바로 아래에있는 내 소스 코드에 따라 : 불행하게도

IntPtr buffer = viewer.Image.Bitmap.GetHbitmap(); 

byte[] pPixelBuffer = new byte[16]; //16 bytes allocation 
Marshal.Copy(buffer, pPixelBuffer, 0, 9); //I copy the 9 first bytes into pPixelBuffer 

, 나는 방법 '에 액세스 위반 예외가 부'! 그리고 나는 왜 그런지 이해하지 못합니다.

아무도 도와 줄 수 없습니까?

미리 감사드립니다.

답변

0

안전하지 않은 상황에서 IntPtrvoid* 번으로 전송할 수 있습니다. 당신은 이것을 할 수 있습니다 :

unsafe 
{ 
    var bytePtr = (byte*)(void*)buffer; 

    // Here use *bytePtr to get the byte value at bytePtr, just like in C/C++ 
} 
+0

가 리소스에 대한 포인터 포인트 네이티브 API로부터 획득하지 @AlexD 때 들어가는없이 byte[]IntPtr의 내용을 복사 할 수 있습니다. GC는 .NET 객체 만 재배치 할 수 있으며,'fixed'는 바로 그 것을 방지합니다. 기본 객체는 메모리에서 이동하지 않습니다. –

+0

EMGU에서 기본 API를 사용하기 때문에 프레임 비디오 버퍼를 인쇄 할 수 없다고 설명하고 있습니까? Visual Studio 디버거에서 내 'ptr'포인터가 유효하지 않은 포인터임을 알면 정상입니다. 그래서 그 내용을 인쇄 할 수 없습니까? – user1364743

+0

@ user1364743 그런 말은하지 않습니다. 내 의견은 삭제 된 이전 댓글에 대한 답변이었습니다. 나는 emgu를 모른다. 그러나 IntPtr이 0이 아닌 한, 그것은 어떤 데이터를 가리키고, 당신은 그 데이터를 대답의 방법으로 읽을 수 있어야한다. 버퍼가 비디오 프레임을 가리키면 읽을 수 있어야합니다. –

관련 문제