2015-10-28 7 views
5

Ogni volta che voglio convertire il mio SoftwareBitmap in un WriteableBitmap ottengo la seguente eccezione: System.Runtime.InteropServices.COMException.Converti SoftwareBitmap in WriteableBitmap

Ecco il mio frammento di codice per questo:

private async void Start(object sender, RoutedEventArgs e) 
     { 

      _MediaCapture = new MediaCapture(); 
      await _MediaCapture.InitializeAsync(); 

      mediaElement.Source = _MediaCapture; 
      await _MediaCapture.StartPreviewAsync(); 
      DispatcherTimer timer = new DispatcherTimer(); 
      timer.Interval = new TimeSpan(0, 0, 0, 1); 
      timer.Tick += HandleTimerTick; 
      timer.Start(); 
     } 

     private async void HandleTimerTick(object Sender, object E) 
     { 


      var frame = await _MediaCapture.GetPreviewFrameAsync(); 
      SoftwareBitmap frameBitmap = frame.SoftwareBitmap; 
      WriteableBitmap bitmap = new WriteableBitmap(frameBitmap.PixelWidth, frameBitmap.PixelHeight); 
      try 
      { 
       frameBitmap.CopyToBuffer(bitmap.PixelBuffer); 
      } 
      catch (Exception) 
      { 
       Debug.WriteLine("Exception "); 
      } 
     } 

La linea

frameBitmap.CopyToBuffer(bitmap.PixelBuffer); 

sta gettando l'eccezione.

Sto eseguendo il debug su un dispositivo remoto x64.

+0

Qual è l'eccezione generata? –

+0

@Dmitry Bychenko Guarda sopra: System.Runtime.InteropServices.COMException – TheTanic

+0

Nota a margine: * deglutizione * eccezioni come 'catch (Exception) {Debug.WriteLine (" Exception "); } 'è una * pessima pratica *. –

risposta

6

Posso riprodurre questo problema utilizzando il tuo codice. È causato da frame.SoftwareBitmap restituisce sempre null.

È possibile risolvere questo problema utilizzando il codice come segue:

private async void button_Click(object sender, RoutedEventArgs e) 
    { 
     _mediaCapture = new MediaCapture(); 

     await _mediaCapture.InitializeAsync(); 

     mediaElement.Source = _mediaCapture; 

     await _mediaCapture.StartPreviewAsync(); 

     DispatcherTimer timer = new DispatcherTimer(); 
     timer.Interval = new TimeSpan(0, 0, 0, 1); 
     timer.Tick += Timer_Tick; 
     timer.Start(); 
    } 

    private async void Timer_Tick(object sender, object e) 
    { 
     var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties; 

     var videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height); 

     var frame = await _mediaCapture.GetPreviewFrameAsync(videoFrame); 

     SoftwareBitmap frameBitmap = frame.SoftwareBitmap; 

     WriteableBitmap bitmap = new WriteableBitmap(frameBitmap.PixelWidth, frameBitmap.PixelHeight); 

     frameBitmap.CopyToBuffer(bitmap.PixelBuffer); 

     Debug.WriteLine("done"); 
    } 
+0

Funziona bene. Grazie – TheTanic

+0

@Jeffrey Non capisco come questo aiuti ... Sembra che l'unica vera differenza sta usando il valore di ritorno di GetPreviewFrameAsync. Non ha senso! Quella funzione non usa il VideoFrame passato da riempire? Dovrebbe essere documentato diversamente se così fosse. Puoi anche dirmi se c'è un colpo perfetto se si specifica un diverso formato di pixel bitmap in InitializeAsync rispetto a VideoFrame? –

+0

@Jeffrey Per essere chiari ... funziona! Sono solo confuso perché. –