Archived

This topic is now archived and is closed to further replies.

peckerpeck

Retrieving BMP values from GDI

Recommended Posts

Hey guys i''m trying to open a bitmap simply to read out its values to generate a heightmap. Simple...i thought. just a couple of calls to the GDI. Here''s the code: BITMAP bmp; HBITMAP hBMP = NULL; float *pfHeightMap = NULL; BYTE *pByte = NULL; hBMP = (HBITMAP) LoadImage( NULL, strFilename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION ); if ( hBMP == NULL ) return false; hr = GetObject( hBMP, sizeof(bmp), &bmp ); if ( hr == 0 ) return false; m_iHMHeight = bmp.bmHeight; m_iHMWidth = bmp.bmWidth; // Print each val to debug screen pByte = (BYTE*)&bmp.bmBits; for ( int q=0; qoutput(outall); pByte++; } The bitmap is loading, I''ve tried 4 different ones and the width and height always get set to the pixel width and height of the bitmap. But the data (bmBits) has a few vals but nothing that even remotely resembles the bitmap values. The bitmap i''m using is just a tiny one for test purposes, it''s 3x2 and I''m saving it in Photoshop as RGB. Five of the pixels are greyscale but the last is very much red (just for more testing purposes). The bmPlanes val is 1 when i use that bitmap or even just one with all greyscale vals, so I''m led to believe that the GDI is opening it as greyscale. I assumed I''d find the b,g,r,0 components in 4-byte boundaries in the data but I''m obviously not. Any ideas?

Share this post


Link to post
Share on other sites
If you are using photoshop you can just save as a raw grayscale file with 1 byte per pixel. Image->Mode->Grayscale. File->SaveAs->change type to raw. Ignore the part where photoshop asks you for a header.

You can read the .raw file with:
  
BYTE * pbHieghtField = new BYTE [ width * hieght ];

std::ifstream file;
file.open (filename, std::ios::binary );
file.read ( (char *)pbHieghtField, width * hieght );
file.close();

Share this post


Link to post
Share on other sites
I''m not sure about the RGB saving option in Photoshop but does it definitely guarantee that it saves the bitmap with 32 bits per pixel?

It sounds as though you are expecting each pixel to be formatted thus:

RRGGBBAA
ff000000 (red, for example)

But it could be that it''s saving the bitmap with palette information so the pixel information is just indices into a palette?

What is bmWidthBytes compared to bmWidth? This should tell you roughly how many bytes are being used for the number of pixels. Of course this is word aligned so it might be worth trying with a bitmap of width divisible by two.

Share this post


Link to post
Share on other sites
invective''s right in that it is saving at a 24-bit depth:
r-g-b-r-g-b...
i opened the bitmap in a hex editor and its fine and the
data in bmBits is right where it should be. thanks for the idea with the raw file, but i want it robust enough to deal with mono/rgb bitmaps. it''s as if the pointer is getting the wrong @.

*furrowed brow*

Share this post


Link to post
Share on other sites
quote:

how do you do that much cleaner form of ''quoting''


Enclose text beween the source and /source tags: source or /source with square brackets [] around it.

quote:

but i want it robust enough to deal with mono/rgb bitmaps



if you are making a hieghtfield, you need only one channel of color information anyways, which is why I suggest raw grayscale over any other format, but if you want to be maximally flexable:

0. Retrieve size of surface: D3DXGetImageInfoFromFile
1. Create a 24 bit Surface: IDirect3DDevice8::CreateImageSurface
2. Load image onto surface: D3DXLoadSurfaceFromFile
3. Read one channel out of the surface: IDirect3DSurface8::LockRect

If you do this, you are guaranteed always to have the file converted to 24 bit RGB interleaved, no matter the original format, and you get support for .bmp, .dds, .dib, .jpg, .png, and .tga

Share this post


Link to post
Share on other sites