使用wxWidgets将内存中的8位灰度图像缓冲区绘制成屏幕

时间:2013-05-15 19:00:31

标签: c++ image wxwidgets

我想将8位灰度图像数据绘制到wxPaintDC,但我遇到了麻烦。数据在uint8_t数组中可供我使用。请参阅下面的非工作代码(这是几次尝试之一)。我能够使用其他wxPaintDC :: Draw *函数绘制,所以我相信其他一切都设置得很好。

uint8_t testBuffer[] = 
{   
    250, 220, 222, 223, 210,
    186, 22, 29, 89, 110,
    250, 220, 222, 203, 210,
    240, 120, 220, 123, 210,
    230, 210, 252, 223, 210
};
wxBitmap cameraImage(5, 5, 8);
wxNativePixelData cameraImageData(cameraImage);
wxNativePixelData::Iterator p(cameraImageData);
for(unsigned y = 0; y < 5; ++y)
{
    wxNativePixelData::Iterator rowStart = p;
    for(unsigned x = 0; x < 5; ++x, ++p)
    {
        uint8_t value = testBuffer[5 * y + x];
        p.Red() = value;
        p.Green() = value;
        p.Blue() = value;
    }
    p = rowStart;
    p.OffsetY(cameraImageData, 1);
}

 // _dialogDrawingCanvas is a wxPaintDC*
_dialogDrawingCanvas->DrawBitmap(cameraImage, 50, 50);

修改 我根据Thomas Matthews的建议看了wxImage。使用wxImage在我使用testBuffer时起作用,但在我使用实际缓冲区时则不行。

这有效:

uint8_t testBuffer[] = 
{   
    250, 220, 222, 223, 210,
    186, 22, 29, 89, 110,
    250, 220, 222, 203, 210,
    240, 120, 220, 123, 210,
    230, 210, 252, 223, 210
};
wxImage image(5, 5, testBuffer, true);
wxBitmap bmp(image);
_dialogDrawingCanvas->DrawBitmap(bmp, 50, 50);

但是,下面的代码没有。我在wxBitmap ctor中崩溃了。

// Returns instance of a class that provides access to camera image.
CameraImage camImage = grabCameraImage(); 
uint8_t* buf = camImage.getBuffer();
wxImage image(camImage.getWidth(), camImage.getHeight(), buf, true);
wxBitmap bmp(image); // Crashes here.
_dialogDrawingCanvas->DrawBitmap(bmp, 50, 50);

我得到的崩溃是:

  

[编辑]中的0x000007fdcf824b5b的第一次机会异常.exe:0xC0000005:访问冲突读取位置0x000000000304d27a。   [编辑]中的0x000007fdcf824b5b处的未处理异常.exe:0xC000041D:在用户回调期间遇到未处理的异常。

编辑2 我将wxWidgets DLL链接到其源代码并跟踪到对wxBitmap ctor的调用。看起来它至少需要24BPP并且在wxImage缓冲区的末尾开始读取并向后移动,所以它一旦尝试访问它认为是缓冲区的最后3个字节就会崩溃。看起来像wxBitmap构造函数的depth参数被忽略了。我想也许这不是testBuffer的问题,因为它是一个固定大小的数组。

1 个答案:

答案 0 :(得分:1)

这在我的编辑中基本上得到了解答,但问题是由在缓冲区中使用8个BPP数据引起的。我能够完成我想做的事情如下:

CameraImage camImage = grabCameraImage(); 
wxImage image(camImage.getWidth(), camImage.getHeight());
const uint8_t* cameraBuffer = camImage.getBuffer();
for(uint16_t y = 0; y < camImage.getHeight(); ++y)
{
    for(uint16_t x = 0; x < camImage.getWidth(); ++x)
    {
        uint8_t intensity = cameraBuffer[y * camImage.getWidth() + x];
        image.SetRGB(x, y, intensity, intensity, intensity);
    }
}
wxBitmap bmp(image, 8);
_dialogDrawingCanvas->DrawBitmap(bmp, 50, 50);