【问题标题】:App MediaFrameReader always returns null BitmapApp MediaFrameReader 总是返回空位图
【发布时间】:2021-03-21 22:10:16
【问题描述】:

我正在使用MediaCapture 在屏幕上预览摄像头,效果很好。

但是,我需要访问我的应用程序中的当前帧。因此我将FrameReader 添加到MediaCapture 以获取事件Reader_FrameArrived。

所以事件正在运行,但是位图本身始终为空。

我实现了 ecent 回调,就像示例中所示:

var mediaFrameReference = sender.TryAcquireLatestFrame();
var videoMediaFrame = mediaFrameReference?.VideoMediaFrame;
var softwareBitmap = videoMediaFrame?.SoftwareBitmap;

if (softwareBitmap != null)
{
    Debug.WriteLine("here");
}
else
{
    return;
}

这就是我初始化阅读器的方式:

var frameSourceGroups = await MediaFrameSourceGroup.FindAllAsync();

var allGroups = await MediaFrameSourceGroup.FindAllAsync();
var eligibleGroups = allGroups.Select(g => new
{
    Group = g,

    // For each source kind, find the source which offers that kind of media frame,
    // or null if there is no such source.
    SourceInfos = new MediaFrameSourceInfo[]
    {
        g.SourceInfos.FirstOrDefault(info => info.SourceKind == MediaFrameSourceKind.Color),
        g.SourceInfos.FirstOrDefault(info => info.SourceKind == MediaFrameSourceKind.Depth),
        g.SourceInfos.FirstOrDefault(info => info.SourceKind == MediaFrameSourceKind.Infrared),
    }
}).Where(g => g.SourceInfos.Any(info => info != null)).ToList();

if (eligibleGroups.Count == 0)
{
    System.Diagnostics.Debug.WriteLine("No source group with color, depth or infrared found.");
    return;
}

var selectedGroupIndex = 0; // Select the first eligible group
MediaFrameSourceGroup selectedGroup = eligibleGroups[selectedGroupIndex].Group;
MediaFrameSourceInfo colorSourceInfo = eligibleGroups[selectedGroupIndex].SourceInfos[0];
MediaFrameSourceInfo infraredSourceInfo = eligibleGroups[selectedGroupIndex].SourceInfos[1];
MediaFrameSourceInfo depthSourceInfo = eligibleGroups[selectedGroupIndex].SourceInfos[2];

//_mediaCapture.FrameSources.TryGetValue(cameraDevice.Id, out _source);
var colorFrameSource = _mediaCapture.FrameSources[colorSourceInfo.Id];

if (colorFrameSource != null)
{
    _reader = await _mediaCapture.CreateFrameReaderAsync(colorFrameSource, MediaEncodingSubtypes.Argb32);
    _reader.FrameArrived += Reader_FrameArrived;
    
    MediaFrameReaderStartStatus result = await _reader.StartAsync();

    Debug.WriteLine(result.ToString());
}

任何想法为什么位图可能为空?

【问题讨论】:

    标签: xamarin xamarin.forms uwp xamarin.uwp mediacapture


    【解决方案1】:

    我正在使用 MediaCapture 在屏幕上预览摄像头,效果很好。

    对于场景,我们建议你使用MediaCapture类捕获位图,它包含GetPreviewFrameAsync方法从捕获设备获取预览帧然后将其转换为SoftwareBitmap

    private async Task GetPreviewFrameAsSoftwareBitmapAsync()
    {
        // Get information about the preview
        var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;
    
        // Create the video frame to request a SoftwareBitmap preview frame
        var videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height);
    
        // Capture the preview frame
        using (var currentFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame))
        {
            // Collect the resulting frame
            SoftwareBitmap previewFrame = currentFrame.SoftwareBitmap;
    
            // Show the frame information
            FrameInfoTextBlock.Text = String.Format("{0}x{1} {2}", previewFrame.PixelWidth, previewFrame.PixelHeight, previewFrame.BitmapPixelFormat);
    
            // Add a simple green filter effect to the SoftwareBitmap
            if (GreenEffectCheckBox.IsChecked == true)
            {
                ApplyGreenFilter(previewFrame);
            }
    
            // Show the frame (as is, no rotation is being applied)
            if (ShowFrameCheckBox.IsChecked == true)
            {
                // Create a SoftwareBitmapSource to display the SoftwareBitmap to the user
                var sbSource = new SoftwareBitmapSource();
                await sbSource.SetBitmapAsync(previewFrame);
    
                // Display it in the Image control
                PreviewFrameImage.Source = sbSource;
            }
    
            // Save the frame (as is, no rotation is being applied)
            if (SaveFrameCheckBox.IsChecked == true)
            {
                var file = await _captureFolder.CreateFileAsync("PreviewFrame.jpg", CreationCollisionOption.GenerateUniqueName);
    
                Debug.WriteLine("Saving preview frame to " + file.Path);
    
                await SaveSoftwareBitmapAsync(previewFrame, file);
            }
        }
    }
    

    这里是官方code sample,您可以直接参考。

    【讨论】:

    • 感谢您的建议。是否有一个事件/回调我可以用来获取每个新帧?或者我还需要 FrameReader 吗?
    • 以上代码示例没有使用FrameReader,可以直接调用GetPreviewFrameAsSoftwareBitmapAsync方法获取位图。
    • 是的,但是有没有办法让我总是通过事件/回调在这里获取新框架?我不想总是循环调用函数
    • 是的,我检查了你的代码,它看起来来自came frame 代码示例。它使用ConvertToDisplayableImage 从帧中获取图像。请看一看。
    猜你喜欢
    • 2014-05-01
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 2016-07-11
    • 2017-12-19
    • 2019-12-02
    • 1970-01-01
    相关资源
    最近更新 更多