在Windows手机silverlight中,我在启动预览视频时使用PhotoCamera获取缓冲帧,在通用应用中我使用MediaCapture,但我不知道如何获取预览缓冲区。
由于
答案 0 :(得分:8)
由于Windows运行时没有Silverlight的PhotoCaptureDevice
类,因此无法使用非常有用的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(商店)应用开始,通过NuGet PM安装Lumia Imaging SDK。此示例在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;
}
}
你可能想知道......我如何抓住previewBuffer?你不需要!
_writeableBitmap
对象始终保持相机中的最新帧,因此您可以随意执行任何操作。
答案 1 :(得分:0)
我的其他答案对于针对Windows 8.1的通用应用仍然有效 - 但对于那些使用UWP应用定位Windows 10的应用,现在有一个更简单的答案。
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);