C ++ / CX如何从缓冲区和缓冲区计数创建BitmapImage

时间:2015-01-09 14:44:19

标签: bitmap count buffer bitmapimage c++-cx

我将mediaCapture与AddEffectsAsync一起使用,以便在相机上设置MFT。使用该MFT,我能够从MFT返回每帧的数据。现在位图来自Nokia :: Ghraphics :: Imaging :: Bitmap类。 在下面的代码中,我从中获取缓冲区和缓冲区的大小,并将其发送到我的应用程序:

void TransformImage_NV12(
const D2D_RECT_U &rcDest,
_Inout_updates_(_Inexpressible_(2 * lDestStride * dwHeightInPixels)) BYTE *pDest,
_In_ LONG lDestStride,
_In_reads_(_Inexpressible_(2 * lSrcStride * dwHeightInPixels)) const BYTE *pSrc,
_In_ LONG lSrcStride,
_In_ DWORD dwWidthInPixels,
_In_ DWORD dwHeightInPixels,
IVector<IImageProvider^>^ providers)
{

    auto size = Windows::Foundation::Size(dwWidthInPixels, dwHeightInPixels);
    auto totalbytes = (int)dwHeightInPixels * (int)dwWidthInPixels * 3 / 2;

    Nokia::Graphics::Imaging::Bitmap^ m_BitmapToProcess = AsBitmapNV12(pSrc, (unsigned int)size.Width, (unsigned int)size.Height);

    BitmapImageSource^ source = ref new BitmapImageSource(m_BitmapToProcess);
    auto first = providers->GetAt(0);
    ((IImageConsumer^)first)->Source = source;

    auto last = providers->GetAt(providers->Size - 1);

    BitmapRenderer^ renderer = ref new BitmapRenderer(last, ColorMode::Yuv420Sp);

    auto renderOp = renderer->RenderAsync();
    auto renderTask = create_task(renderOp);

    renderTask.then([pDest, totalbytes](Nokia::Graphics::Imaging::Bitmap^ bitmap)
    {
        auto count = bitmap->Buffers->Length;
        unsigned char* data = FromIBuffer(bitmap->Buffers[0]->Buffer);
        CMFTWrapper::FrameData = data;
        CMFTWrapper::count = count;
        SetEvent(CMFTWrapper::FrameEvent());
        CopyMemory(pDest, data, totalbytes);
    }).wait();
}

这样做我在我的应用程序中调用了回调函数:

void VideoCapturerSampleCallback(struct LmiVideoCapturer_* capturer, const LmiVideoFrame* videoFrame, LmiVoidPtr userData)
{
    App2::MainPage^ ctx = context;
    Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([ctx]()
    {          
        Windows::UI::Xaml::Media::Imaging::BitmapImage^ bitmapImage =
        ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
        //TODO will need to create it from the buffer
        media->Source = bitmapImage;
}));
}

在这里,我可以使用CMFTWrapper类访问缓冲区和MFT中的计数,我已经保存了数据。 我的问题是如何在我创建的bitmapImage中加载这些数据? 我发现一些代码向我展示了如何构建一个bitmapImage,但大多数代码都在C#中,我需要使用C ++ / cx

2 个答案:

答案 0 :(得分:1)

您想使用Windows.UI.Xaml.Media.Imaging.WriteableBitmap

使用WriteableBitmap,您需要使用IBufferByteAccess(包括robuffer.h来获取此定义):

using namespace Microsoft::WRL;
auto xaml_image = ref new WriteableBitmap(width, height);

// Cast PixelBuffer to Object^, then to its underlying IInspectable interface.
Object^ obj = xaml_image->PixelBuffer;
ComPtr<IInspectable> insp(reinterpret_cast<IInspectable*>(obj));

// Query the IBufferByteAccess interface.
ComPtr<IBufferByteAccess> bufferByteAccess;
ThrowIfFailed(insp.As(&bufferByteAccess));

// Get native pointer to the buffer data.
byte* pixels = nullptr;
ThrowIfFailed(bufferByteAccess->Buffer(&pixels));

// TODO: copy image data in BGRA8 format into 'pixels' buffer
// memcpy_s(pixels, xaml_image->PixelBuffer->Capacity, data, width*height*4);

// Set final source
media->Source = xaml_image;

答案 1 :(得分:0)

编辑答案,因为我显然没有正确地阅读这个问题。

您是否看过CameraPreviewImageSource btw?它使用MF引擎,让您处理相机预览流。

顺便说一句,现在有一个2.0版的重命名为Lumia Imaging SDK。升级nuget包以获得它。