Recuperare un fotogramma di anteprima

Questo argomento illustra come ottenere un singolo fotogramma di anteprima dal flusso di anteprima dell'acquisizione multimediale.

Nota

Questo articolo si basa sui concetti e sul codice descritti in Acquisizione di foto, video e audio di base con MediaCapture, che descrive i passaggi necessari per implementare l'acquisizione di foto e video di base. È consigliabile acquisire familiarità con il modello di acquisizione multimediale di base in questo articolo prima di passare a scenari di acquisizione più avanzati. Il codice in questo articolo presuppone che l'app disponga già di un'istanza di MediaCapture che è stata inizializzata correttamente e che si disponga di un oggetto CaptureElement con un flusso di anteprima video attivo.

Oltre agli spazi dei nomi necessari per l'acquisizione multimediale di base, l'acquisizione di un frame di anteprima richiede lo spazio dei nomi seguente.

using Windows.Media;

Quando si richiede un frame di anteprima, è possibile specificare il formato in cui si desidera ricevere il fotogramma creando un oggetto VideoFrame con il formato desiderato. Questo esempio crea un fotogramma video che corrisponde alla stessa risoluzione del flusso di anteprima chiamando VideoDeviceController.GetMediaStreamProperties e specificando MediaStreamType.VideoPreview per richiedere le proprietà per il flusso di anteprima. La larghezza e l'altezza del flusso di anteprima vengono usate per creare il nuovo fotogramma video.

// Get information about the preview
var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;

// Create a video frame in the desired format for the preview frame
VideoFrame videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height);

Se l'oggetto MediaCapture viene inizializzato e si dispone di un flusso di anteprima attivo, chiamare GetPreviewFrameAsync per ottenere un flusso di anteprima. Passare il fotogramma video creato nell'ultimo passaggio per specificare il formato del fotogramma restituito.

VideoFrame previewFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame);

Ottenere una rappresentazione SoftwareBitmap del fotogramma di anteprima accedendo alla proprietà SoftwareBitmap dell'oggetto VideoFrame. Per informazioni sul salvataggio, il caricamento e la modifica delle bitmap software, vedere Imaging.

SoftwareBitmap previewBitmap = previewFrame.SoftwareBitmap;

Puoi anche ottenere una rappresentazione IDirect3DSurface del fotogramma di anteprima se vuoi usare l'immagine con le API Direct3D.

var previewSurface = previewFrame.Direct3DSurface;

Importante

La proprietà SoftwareBitmap o la proprietà Direct3DSurface del VideoFrame restituito possono essere Null a seconda della modalità di chiamata a GetPreviewFrameAsync e anche a seconda del dispositivo in cui è in esecuzione l'app.

  • Se si chiama l'overload di GetPreviewFrameAsync che accetta un argomento VideoFrame, il VideoFrame restituito avrà un SoftwareBitmap non null e la proprietà Direct3DSurface sarà Null.
  • Se si chiama l'overload di GetPreviewFrameAsync che non ha argomenti in un dispositivo che usa una superficie Direct3D per rappresentare internamente il frame, la proprietà Direct3DSurface sarà diversa da null e la proprietà SoftwareBitmap sarà Null.
  • Se si chiama l'overload di GetPreviewFrameAsync che non ha argomenti in un dispositivo che non usa una superficie Direct3D per rappresentare internamente il frame, la proprietà SoftwareBitmap sarà diversa da null e la proprietà Direct3DSurface sarà Null.

L'app deve sempre verificare la presenza di un valore Null prima di provare a operare sugli oggetti restituiti dalle proprietà SoftwareBitmap o Direct3DSurface.

Al termine dell'uso del frame di anteprima, assicurarsi di chiamare il relativo metodo Close (proiettato in Dispose in C#) per liberare le risorse usate dal frame. In alternativa, usare il modello using, che elimina automaticamente l'oggetto.

previewFrame.Dispose();
previewFrame = null;