App MediaFrameReader 总是返回空位图

Posted

技术标签:

【中文标题】App MediaFrameReader 总是返回空位图【英文标题】:App MediaFrameReader always returns null Bitmap 【发布时间】: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());

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

【问题讨论】:

【参考方案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("0x1 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 从帧中获取图像。请看一看。

以上是关于App MediaFrameReader 总是返回空位图的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的MacBook air 在app里下载软件总是失败,让我返回已购页面再试一次?

通过 .bat 执行 Sqlplus 总是返回 0

iOS App:窗口旋转总是纵向而不是横向

权限总是返回 never_ask_again

Core Data 计算属性总是返回 0

位置索引在 getView 中总是返回 0