0
votes

I am trying to load an image that is given to me as a BITMAPINFO* and a uchar array. The documentation states that it is a standard Microsoft device independent bitmap (DIB) with 8-bit pixels and a 256-entry color table.

I am curently able to open this image through:

BITMAPINFO* bmih = givenBITMAPINFO;
uchar* data = givenData;

QImage img = QImage(data, bmih->biWidth, bmih->biHeight, QImage::Format_Grayscale8);

But I have two problems with that:

  1. the image is in QImage::Format_Grayscale8 when the documentation states an 8-bit pixels and a 256-entry color table;

  2. the image is upside down and mirrored. This come from the way the bitmap data is stored in Win32.

Anyone knows how I can load properly this image?

1
The color information for an 8-bit DIB is stored in a color palette. That color palette follows the BITMAPINFOHEADER in a standard bitmap file. Unless the pointer you have points at a BITMAPINFOHEADER followed by the color palette there is no way for you to reconcile the color information. - IInspectable
Okay, I think I can get the color table from the BITMAPINFO. But then the image is backward, what would be the most efficient way to load it streight? - firehelm
It doesn't appear that any of the QImage c'tors are capable of flipping the image, so you would have to apply QImage::mirrored as a second step. Also note that there is QImage::setColorTable. In combination with a QImage::Format_Indexed8 image format you should be able to construct your image. - IInspectable
Does the QImage::mirrored() have a good complexity or should I use another library? - firehelm
If in doubt, measure. Vertically flipping an image inevitably results in copying all pixel data in memory. Any imaging library is going to have to do this. - IInspectable

1 Answers

0
votes

By casting the provided header to a BITMAPINFO instead of a BITMAPINFOHEADER I have access to the color table and then apply a trasformation to get a streight image:

BITMAPINFO* bmi = givenHeader;
uchar* data = givenData;

QImage img = QImage(data, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, QImage::Format_Indexed8);

img.setColorCount(256);
for (int i=0; i<256; ++i){
    RGBQUAD* rgbBmi = bmi->bmiColors;
    img.setColor(i, qRgb(rgbBmi[i].rgbRed, rgbBmi[i].rgbGreen, rgbBmi[i].rgbBlue))
}

img = img.mirrored(false, true);