Re: Attempting to access 1 bit bitmap raw pixel data

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



1) Per the docs the bits are located as follows:
char* pBits = (char*)((PBYTE)infoHeader + infoHeader.bfOffBits);

2) You need to read the color table.
When you unpack the byte, you get an index
into the color table that represents the color.
The colors are not mandated to be black and white.
And they don't have to be packed as index[0] = black
and index[1] = white.

3) Your buffer needs to hold WORD_ALIGNED_BYTES(width) * height bytes
For your 2x2 bitmap that's 8 bytes.

4) You loop through each scanline
for ( int i = 0; i < height; i++ ) // 2 scan lines
{
// Find the byte on which this scanline begins
DWORD ByteIndex = (height - i - 1) * WORD_ALIGNED_BYTES(width);
// loop through one WORD aligned scanline
for ( int j = 0; j < WORD_ALIGNED_BYTES(width); j++ ) // rowstride
= 4bytes
for ( int k = 0; k < 8; k++ ) // packed as 8 pixels per byte
{
// locate the bit
BYTE BitNumber = (BYTE)( 7 - (k % 8) );
// get the color index
int Index = (pBits[j] << BitNumber) & 0x80 ? 1 : 0;
// look up the color in the color table
COLORREF color = RGB(pbmi->bmiColors[Index].rgbRed,
pbmi->bmiColors[Index].rgbGreen,
pbmi->bmiColors[Index].rgbBlue);
}
}

<SteveKlett@xxxxxxxxx> wrote in message
news:1126113135.191887.289410@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> OK, making progress, but still not there. This could be the last ?
> though(I hope).
>
> After looping through and checking each pixel of the 4 pixel bitmap, I
> expected to see only 1 of the 4 pixels to be different(my bitmap looks
> like this:
> [X][ ]
> [ ][ ]
> Where the X is a black pixel)
>
> But instead, 2 seem to be black. Anyway, I'm stuck(again) and hoped to
> paste code so that someone might point out my error.
>
> <code>
> void GetBitmapBitsUglyVersion(CString& filename)
> {
> #define WORD_ALIGNED_BYTES(width)((((width-1)>>5)+1)<<2)
>
>
> CFile file(filename, CFile::modeRead);
> unsigned long long length = file.GetLength();
>
> char* pBuffer = new char[length+1];
> char* pDataPtr = pBuffer;
>
> file.Read(pBuffer, length);
> file.Close();
>
> PBITMAPFILEHEADER fileHeader = (PBITMAPFILEHEADER)pDataPtr;
> pDataPtr += sizeof(BITMAPFILEHEADER);
>
> PBITMAPINFOHEADER infoHeader = (PBITMAPINFOHEADER)pDataPtr;
> unsigned int width = infoHeader->biWidth;
> unsigned int height = infoHeader->biHeight;
> unsigned int bitCount = infoHeader->biBitCount;
> unsigned short numPlanes = infoHeader->biPlanes;
>
> pDataPtr+= sizeof(BITMAPINFOHEADER);
> pDataPtr+=(numPlanes+1)*sizeof(RGBQUAD); // skip the color table
> (it's B&W)
>
> char* pBits = pDataPtr;
>
>
> char buffer[128];
>
> for(int i=0; i < width; i++)
> {
> for(int j=0; j < height; j++)
> {
> // Find the byte on which this scanline begins
> DWORD ByteIndex = (height - j - 1) * WORD_ALIGNED_BYTES(width);
> // Find the byte containing this pixel
> ByteIndex += (i >> 3);
> // Which byte is it?
> BYTE BitNumber = (BYTE)( 7 - (i % 8) );
> // get the color index
> int Index = (pBits[ByteIndex] << BitNumber) & 0x80 ? 1 : 0;
> if(Index)
> {
> sprintf(buffer, "x:%d, y:%d is high\r\n", i, j);
> OutputDebugString(buffer);
> }
> }
> }
>
> if(pBuffer)
> delete[] pBuffer;
> }
> </code>
>
> Hopefully someone will see the problem and hopefully it will be a basic
> one ;)
>
> Thanks for the help!
> -Steve
>


.



Relevant Pages

  • =?iso-8859-1?Q?Re:_CopyFromScreen_Bitmap_als_Bild_speichern_und_Gr=F6=DFe?= =?iso-8859&#
    ... wenn du mit der Auflösung festlegst, dass in einem Zoll 96 Pixel darzustellen sind, dann belegen 200 Pixel etwa 55 mm. ... Dim bmp As Bitmap = New Bitmap ... g.DrawImage(bmp, 0, 0, breite, hoehe) ... Wie Du erkennen kannst ist die Linke Grafik nur noch halb so breit wie die Obere, ...
    (microsoft.public.de.german.entwickler.dotnet.vb)
  • Re: VB3 is making my head spin!
    ... > and displaying it pixel by pixel] tell me how. ... compressed bitmap from an original 24 but full colour bitmap that is held on disk as a standard ... It shows you how to load a full colour 24bit .bmp file from disk and count ... Dim z As Long, t1 As Long, t2 As Long ...
    (comp.lang.basic.visual.misc)
  • Re: PictureBox max width
    ... boxes at the same time. ... The maximum Width of a memory bitmap can be very much greater than the 16383 VB PictureBox limit. ... If your desired overall size is very much larger than this amount, and especially if you are going to run it on machines with limited memory, then you might instead wish to use DIBSections (which are a bit smaller because a full colour 24 bit DIB requires only three bytes per pixel) and which I believe can be paged to disk, although you will still run into problems with DIBSections if you ever get up to extremely large overall sizes. ... I'm afraid you're kidding yourself with the Frame Control, ...
    (microsoft.public.vb.general.discussion)
  • Re: How to fill a region
    ... It uses direct pixel access via LockBits and no unsafe code. ... BitmapData bmd) ... /// Fills a bitmap with color. ... Graphics g=Graphics.FromImage; ...
    (microsoft.public.dotnet.framework.drawing)
  • Re: Lineal skalieren
    ... Das Pixel auf dem Bildschirm ist auch ... Eine Bitmap ist zunächst nichts anderes als ein zweidimensionales ... Aber hat ein Pixel in diesem Array eine Fläche? ... Digitalisierung eines Bildes eine Methode ist, ...
    (microsoft.public.de.german.entwickler.dotnet.vb)