Приложение MediaFrameReader всегда возвращает null Bitmap

Я использую 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());
}

Любые идеи, почему растровое изображение может быть нулевым?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
216
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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);
        }
    }
}

А вот и официальный пример кода, на который вы можете сослаться напрямую.

спасибо за предложение. есть ли событие/обратный вызов, который я могу использовать для получения каждого нового кадра? Или мне все еще нужен FrameReader для этого?

mojado 10.12.2020 15:37

В приведенном выше примере кода не используется FrameReader, вы можете вызвать метод GetPreviewFrameAsSoftwareBitmapAsync, чтобы напрямую получить растровое изображение.

Nico Zhu 10.12.2020 15:39

да, но есть ли способ, как я всегда буду получать новый кадр через событие/обратный вызов здесь? Я не хочу всегда вызывать функцию в цикле

mojado 10.12.2020 15:43

Да, я проверил ваш код, похоже, он взят из примера кода Come Frame. он использует ConvertToDisplayableImage, чтобы получить изображение из кадра. Пожалуйста, посмотрите.

Nico Zhu 10.12.2020 15:51

Другие вопросы по теме