如何在Windows UWP中将SoftwareBitmap从Bgra8转换为JPEG

时间:2017-05-22 10:27:55

标签: windows uwp c++-cx

如何在Windows UWP中将SoftwareBitmap从Bgra8转换为JPEG。 GetPreviewFrameAsync函数用于在Bgra8中获取videoFrame数据。以下代码出了什么问题?我的jpeg大小为0。

    auto previewProperties = static_cast<MediaProperties::VideoEncodingProperties^>
        (mediaCapture->VideoDeviceController->GetMediaStreamProperties(Capture::MediaStreamType::VideoPreview));
    unsigned int videoFrameWidth = previewProperties->Width;
    unsigned int videoFrameHeight = previewProperties->Height;
    FN_TRACE("%s videoFrameWidth %d videoFrameHeight %d\n",
        __func__, videoFrameWidth, videoFrameHeight);

    // Create the video frame to request a SoftwareBitmap preview frame
    auto videoFrame = ref new VideoFrame(BitmapPixelFormat::Bgra8, videoFrameWidth, videoFrameHeight);

    // Capture the preview frames
    return create_task(mediaCapture->GetPreviewFrameAsync(videoFrame))
        .then([this](VideoFrame^ currentFrame)
    {
        // Collect the resulting frame
        auto previewFrame = currentFrame->SoftwareBitmap;

        auto inputStream = ref new Streams::InMemoryRandomAccessStream();

        create_task(BitmapEncoder::CreateAsync(BitmapEncoder::JpegEncoderId, inputStream))
            .then([this, previewFrame, inputStream](BitmapEncoder^ encoder)
        {
            encoder->SetSoftwareBitmap(previewFrame);
            encoder->FlushAsync();

            FN_TRACE("jpeg size %d\n", inputStream->Size);
            Streams::Buffer^ data = ref new Streams::Buffer(inputStream->Size);
            create_task(inputStream->ReadAsync(data, (unsigned int)inputStream->Size, InputStreamOptions::None));
        });
});

1 个答案:

答案 0 :(得分:0)

Bitmap​Encoder.FlushAsync()方法是一种异步方法。我们应该像下面这样消费它:

// Capture the preview frames
return create_task(mediaCapture->GetPreviewFrameAsync(videoFrame))
    .then([this](VideoFrame^ currentFrame)
{
    // Collect the resulting frame
    auto previewFrame = currentFrame->SoftwareBitmap;

    auto inputStream = ref new Streams::InMemoryRandomAccessStream();

    return create_task(BitmapEncoder::CreateAsync(BitmapEncoder::JpegEncoderId, inputStream))
        .then([this, previewFrame](BitmapEncoder^ encoder)
    {
        encoder->SetSoftwareBitmap(previewFrame);
        return encoder->FlushAsync();
    }).then([this, inputStream]()
    {

        FN_TRACE("jpeg size %d\n", inputStream->Size);
        //TODO
    });
});

然后你应该能够得到合适的尺寸。有关详细信息,请参阅Asynchronous programming in C++