2014-12-10 2 views
2

В Windows silverlightlight я использую PhotoCamera, чтобы получить буферный фрейм при запуске предварительного просмотра, в универсальном приложении вместо этого я использую MediaCapture, но я не знаю, как получить буфер предварительного просмотра.Как получить буфер предварительного просмотра MediaCapture - Универсальное приложение

Благодаря

+0

Этот ответ в настоящее время [используется в других местах] (http://stackoverflow.com/questions/28703586/camerapreviewimagesource-empty-preview-frame?lq=1), который предполагает, что это правильно. Если вы согласны, можете ли вы принять его, чтобы помочь другим с этой проблемой. – thomasf2811

+0

Возможный дубликат [Доступ к кадру предварительного просмотра от MediaCapture] (http://stackoverflow.com/questions/29947225/access-preview-frame-from-mediacapture) – Mike

+0

Не дубликат. Этот ответ велик, но я думаю, что он работает только на Windows 10 и требует разрешения небезопасного кода. Мой ответ использует SDK Lumia Imaging и не имеет ограничений (хотя я думаю, что он намного менее эффективен). – thomasf2811

ответ

8

Поскольку среды выполнения Windows не имеет PhotoCaptureDevice класс Silverlight, в чрезвычайно полезные GetPreviewBufferARGB() и GetPreviewBufferYCbCr() методы не доступны.

Решение, которое вы ищете, это использовать метод MediaCapture.StartPreviewToCustomSinkAsync(), но для этого необходимы навыки C++, которые лучше, чем у меня. Никто, кажется, не решил проблему и поделился своим кодом.

Теперь есть действительно прекрасное решение, в котором используется Lumia Imaging SDK, который не использует класс MediaCapture, но, скорее всего, решит вашу проблему еще лучше.

Сначала проверьте Microsoft example on Github. Это хорошо работает, но довольно сложно, поскольку оно предназначено как для Windows 8.1, так и для Windows Phone 8.1.

Я написал более простой код, просто предназначенный для Windows Phone, для моего собственного понимания. Это может помочь.

Начните с нового приложения C# Windows Phone 8.1 (Store) с SDK Lumia Imaging, установленным через NuGet PM. Этот пример обращается к элементу изображения с x:Name="previewImage" в MainPage.xaml, поэтому убедитесь, что вы его добавили. Вам также понадобится сделать соответствующий импорт до MainPage.xaml.cs, который, как я думаю.

using Lumia.Imaging; 
using System.Threading.Tasks; 
using Windows.UI.Xaml.Media.Imaging; 
using Windows.UI.Core; 
using System.ComponentModel; 

Затем добавьте следующую строку в нужном месте в MainPage.xaml.cs.

private CameraPreviewImageSource _cameraPreviewImageSource; // Using camera as our image source 
private WriteableBitmap _writeableBitmap; 
private FilterEffect _effect; 
private WriteableBitmapRenderer _writeableBitmapRenderer; // renderer for our images 
private bool _isRendering = false; // Used to prevent multiple renderers running at once 

public MainPage() 
{ 
    this.InitializeComponent(); 
    this.NavigationCacheMode = NavigationCacheMode.Required; 
    startCameraPreview(); 
} 

private async Task startCameraPreview() 
{ 
    // Create a camera preview image source (from the Lumia Imaging SDK) 
    _cameraPreviewImageSource = new CameraPreviewImageSource(); 
    await _cameraPreviewImageSource.InitializeAsync(string.Empty); // use the first available camera (ask me if you want code to access other camera) 
    var previewProperties = await _cameraPreviewImageSource.StartPreviewAsync(); 
    _cameraPreviewImageSource.PreviewFrameAvailable += drawPreview; // call the drawPreview method every time a new frame is available 

    // Create a preview bitmap with the correct aspect ratio using the properties object returned when the preview started. 
    var width = 640.0; 
    var height = (width/previewProperties.Width) * previewProperties.Height; 
    var bitmap = new WriteableBitmap((int)width, (int)height); 
    _writeableBitmap = bitmap; 

    // Create a BitmapRenderer to turn the preview Image Source into a bitmap we hold in the PreviewBitmap object 
    _effect = new FilterEffect(_cameraPreviewImageSource); 
    _effect.Filters = new IFilter[0]; // null filter for now 
    _writeableBitmapRenderer = new WriteableBitmapRenderer(_effect, _writeableBitmap); 
} 

private async void drawPreview(IImageSize args) 
{ 
    // Prevent multiple rendering attempts at once 
    if (_isRendering == false) 
    { 
     _isRendering = true; 
     await _writeableBitmapRenderer.RenderAsync(); // Render the image (with no filter) 
     // Draw the image onto the previewImage XAML element 
     await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, 
      () => 
      { 
       previewImage.Source = _writeableBitmap; // previewImage is an image element in MainPage.xaml 
       _writeableBitmap.Invalidate(); // force the PreviewBitmap to redraw 
      }); 
     _isRendering = false; 
    } 
} 

Возможно, вам интересно, как я могу захватить предварительный просмотрBuffer? Вам не нужно!

Объект _writeableBitmap всегда содержит последний кадр с камеры, поэтому вы можете делать с ним все, что вам нравится.

+0

Должна ли быть строка, в которой элемент CaptureElement в XAML связан с CameraPreviewImageSource? –

+0

Привет, Паулина, я так не думаю. В этом примере кода в XAML нет CaptureElement. Каждый раз, когда доступен новый кадр, мы вызываем метод drawPreview, чтобы отобразить его как растровое изображение, а затем нарисовать его на изображении PreviewImage в XAML. Это не очень эффективно, но оно работает, и, похоже, в Windows 10 есть оптимизация, которая делает ее более эффективной. – thomasf2811

+0

Спасибо Томас! :) Ну, похоже, начинать с нуля - это путь, потому что я уже использовал объект MediaCapture и CaptureElement по всему месту> _ < –

0

. Мой другой ответ по-прежнему действителен для универсальных приложений, ориентированных на Windows 8.1, но для тех, кто ориентирован на Windows 10 с приложениями UWP, сейчас гораздо более простой ответ.

Grabbing a preview frame in UWP is easy and well-documented - из существующего объекта MediaCapture это можно сделать в трех строках.

// 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.Height, (int)previewProperties.Width); 

// Grave a preview frame   
VideoFrame previewFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame); 

 Смежные вопросы

  • Нет связанных вопросов^_^