簡體   English   中英

如何在C ++中將Lumia :: Imaging :: Bitmap指向字節緩沖區?

[英]How do I point a Lumia::Imaging::Bitmap at a byte buffer in C++?

對於某些情況,我們有一個包含三個項目的Visual Studio解決方案。 主要項目是C#應用程序,我們有一個C ++庫,該庫本質上是一個圖像渲染管道,並且我們有一個c ++ / cx WinRT組件作為兩者之間的橋梁。

我們正在將某些圖像濾鏡鏈(在C ++庫中)卸載到c ++ / cx WinRT項目中的Lumia Imaging SDK。 由於我們正在使用字節緩沖區,因此不確定如何在不執行復制的情況下將Lumia :: Imaging :: Bitmap ^指向我們的緩沖區。 (我們無法在uchar *(即我們的字節數組)上調用AsBuffer(),因為在C ++領域中我們無法使用該擴展方法。)

所以問題是這樣的: 給某個將實現Lumia過濾器鏈的方法輸入uchar *,我們如何創建一個不會導致復制緩沖區的位圖(或BitmapImageSource)?

這是一些示例代碼,我們需要在這些代碼上填寫空白:

Bitmap^ MyClass::GetBitmapImageDestination(uchar *imageBytes, int imageWidth, int imageHeight, ColorMode colorMode) {
    int channels = colorMode == ColorMode::Gray8 ? 1 : 4;

    IBuffer^ byteBuffer = ..... ????

    return ref new Bitmap(Windows::Foundation::Size((float)imageWidth, (float)imageHeight), colorMode, (uint)(imageWidth * channels), byteBuffer); 
}

好的,所以這是我們周圍的一些駭客,因為它創建了一個副本,因此無法實現我們所需的功能:

Bitmap^ MyClass::GetBitmapImageDestination(uchar *imageBytes, int imageWidth, int imageHeight, ColorMode colorMode) {
    int channels = colorMode == ColorMode::Gray8 ? 1 : 4;

    DataWriter^ writer = ref new DataWriter();
    Platform::ArrayReference<uchar, 1> tempArray(imageBytes, imageWidth * imageHeight * 4);
    writer->WriteBytes(tempArray);
    IBuffer^ byteBuffer = writer->DetachBuffer();   

    return ref new Bitmap(Windows::Foundation::Size((float)imageWidth, (float)imageHeight), colorMode, (uint)(imageWidth * channels), byteBuffer);
}

但是經過一番思考,我們決定嘗試使用我們自己的實現對IBuffer進行子類化。 感謝Jmorrill對MSDN上的這篇文章的幫助:

https://social.msdn.microsoft.com/Forums/en-US/816e5718-224d-4bb7-bf06-230e9c6cda5b/how-to-create-an-ibuffer-from-scratch?forum=winappswithnativecode

這是我們對IBuffer的實現:

class ImageBuffer : public Microsoft::WRL::RuntimeClass<
                           Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRtClassicComMix >,
                           ABI::Windows::Storage::Streams::IBuffer,
                           Windows::Storage::Streams::IBufferByteAccess >
    {

    public:
        virtual ~ImageBuffer()
        {
        }

        STDMETHODIMP RuntimeClassInitialize(UINT totalSize, UCHAR* data)
        {
            _imageLength = totalSize;
            _imageData = data;
            return S_OK;
        }

        STDMETHODIMP Buffer( byte **value)
        {
            *value = &_imageData[0];
            return S_OK;
        }

         STDMETHODIMP get_Capacity(UINT32 *value)
         {
             *value = _imageLength;
             return S_OK;
         }

        STDMETHODIMP get_Length(UINT32 *value)
        {
            *value = _imageLength;
            return S_OK;
        }

        STDMETHODIMP put_Length(UINT32 value)
        {
            if(value > _imageLength)
                return E_INVALIDARG;
            _imageLength = value;
            return S_OK;
        }
    private:
        UINT32 _imageLength;
        UCHAR *_imageData;
};

並且我們使用互操作來創建ImageBuffer實例:

Bitmap^ MyClass::GetBitmapImageDestination(uchar *imageBytes, int imageWidth, int imageHeight, ColorMode colorMode) {
    int channels = colorMode == ColorMode::Gray8 ? 1 : 4;

    ComPtr<ImageBuffer> imageBuffer;
    MakeAndInitialize<ImageBuffer>(&imageBuffer, imageWidth * imageHeight * channels, imageBytes);
    auto iinspectable = (IInspectable*)reinterpret_cast<IInspectable*>(imageBuffer.Get());
    IBuffer^ byteBuffer = reinterpret_cast<IBuffer^>(iinspectable);

    return ref new Bitmap(Windows::Foundation::Size((float)imageWidth, (float)imageHeight), colorMode, (uint)(imageWidth * channels), byteBuffer);
}

希望這對某人有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM