c++ - WinRT C++ (Win10) 从 SoftwareBitmap/BitmapBuffer 访问字节

标签 c++ windows-runtime buffer windows-10 uwp

要在 OpenCV 中处理相机的预览帧,我需要访问原始像素数据/字节。所以,有新的 SoftwareBitmap,它应该正好提供这个。

有一个example对于 c#,但在 visual c++ 中我无法获得 IMemoryBufferByteAccess (见备注)界面工作。

异常代码:

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

    auto buffer = previewFrame->LockBuffer(Windows::Graphics::Imaging::BitmapBufferAccessMode::ReadWrite);
    auto reference = buffer->CreateReference();

    // Get a pointer to the pixel buffer
    byte* pData = nullptr;
    UINT capacity = 0;

    // Obtain ByteAccess
    ComPtr<IUnknown> inspectable = reinterpret_cast<IUnknown*>(buffer);
    // Query the IBufferByteAccess interface.
    Microsoft::WRL::ComPtr<IMemoryBufferByteAccess> bufferByteAccess;
    ThrowIfFailed(inspectable.As(&bufferByteAccess));     // ERROR ---> Throws HRESULT = E_NOINTERFACE

    // Retrieve the buffer data.
    ThrowIfFailed(bufferByteAccess->GetBuffer(_Out_ &pData, _Out_ &capacity));      // ERROR ---> Throws HRESULT = E_NOINTERFACE, because bufferByteAccess is null

我也试过这个:

    HRESULT hr = ((IMemoryBufferByteAccess*)reference)->GetBuffer(&pData, &capacity);

HRESULT 没问题,但我无法访问 pData -> Access Violation reading Memory。

感谢您的帮助。

最佳答案

您应该在 reinterpret_cast 中使用引用而不是缓冲区。

#include "pch.h"
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>

MIDL_INTERFACE("5b0d3235-4dba-4d44-865e-8f1d0e4fd04d") 
IMemoryBufferByteAccess : IUnknown
{
    virtual HRESULT STDMETHODCALLTYPE GetBuffer(
        BYTE   **value,
        UINT32 *capacity
        );
};

        auto previewFrame = currentFrame->SoftwareBitmap;

        auto buffer = previewFrame->LockBuffer(BitmapBufferAccessMode::ReadWrite);

        auto reference = buffer->CreateReference();

        ComPtr<IMemoryBufferByteAccess> bufferByteAccess;

        HRESULT result = reinterpret_cast<IInspectable*>(reference)->QueryInterface(IID_PPV_ARGS(&bufferByteAccess));

        if (result == S_OK)
        {
            WriteLine("Get interface successfully");

            BYTE* data = nullptr;

            UINT32 capacity = 0;

            result = bufferByteAccess->GetBuffer(&data, &capacity);

            if (result == S_OK)
            {
                WriteLine("get data access successfully, capacity: " + capacity);
            }
        }

关于c++ - WinRT C++ (Win10) 从 SoftwareBitmap/BitmapBuffer 访问字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31841790/

相关文章:

c++ - 将 vector 从 c++ dll 重新调整到另一个 c++ exe 时出现问题

c++使用自定义模板库对 vector 对进行排序

windows-runtime - 如何在 WinRT 中设置应用程序启动屏幕背景颜色

windows-runtime - 将 IsDefault 属性设置为 XAML/C# WinRT 应用中的按钮

c++ - 结构中固定大小的数组是否需要在 C++ 析构函数中显式销毁?

c++ - 如何镜像 CGPoint

c# - 本地化 VirtualKey.Control (WinRT)

在 C 中创建 HTTP 客户端以下载网页以供离线查看

bash - 尾-f 文件1 | perl -pe '$_' > file2 不向 file2 输出任何内容

JavamappedByteBuffer和flip()和position()