Click here to Skip to main content
15,902,938 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I'm a self taught beginner and I've spent what seems like days on this one. As I'm stuck again, I'd thought I'd ask the kind people here at Code Project. I have been wanting to iterate through the pixels of large (10K+ pixels by 10K+ pixels) 1bit Windows bitmaps and decided on Lockbits.

' Lock the bitmap's bits and put in array
       Dim FullRect As New Rectangle(0, 0, FWBitmap.Width, FWBitmap.Height)
       Dim bmpData As System.Drawing.Imaging.BitmapData = FWBitmap.LockBits(FullRect, _
           Drawing.Imaging.ImageLockMode.ReadWrite, FWBitmap.PixelFormat)

       ' Get the address of the first line of bitmap.
       Dim ptr As IntPtr = bmpData.Scan0

       ' Declare an array to hold the bytes of the bitmap.
       Dim bytes As Integer = (bmpData.Stride) * (FWBitmap.Height)
       Dim EachByte(bytes - 1) As Byte

       ' Copy the bitmap's RGB values into the array.
       System.Runtime.InteropServices.Marshal.Copy(ptr, EachByte, 0, bytes)

Then I was stepping through and within the bytes with:
 CurrentByte = Math.Truncate((Point.Y * bmpData.Stride) + ((Point.X) / 8))

CurrentByteBit = 8 * ((Point.Y * bmpData.Stride) + ((Point.X) / 8) - CurrentByte) + 1

The array appears okay (although Visual Studio often ceases up when it's very big). However, the pixel values I'm getting out of the array don't appear to resemble the original bitmap. I suspect I am missing something obvious here !?

Your comment refers to the bitmap being RGB. That concerns me that you're on the wrong track.

Let's review how 1-bit images work:
Each pixel in the image is either black or white.
We can store 8 pixels in 1 byte.
Without compression, stride = width / 8 (give or take), and totalbytes = stride * height.
Depending on the file type, and whether it was created on a PC, Mac or other, the first pixel in a byte may = 1 or 128, the second 2 or 64, etc. This is called endianess.

Let's say we had a row of pixels that alternated black and white pixels like
X X X X X X X X X X X X X X X X X X X X X X ...
So each byte would be 0x01 + 0x04 + 0x10 + 0x40 = 0x55
Still with me? (also, see how nice those numbers look? That's why programmers use hex.)

Now let's look at your code.

CurrentByte = Math.Truncate((Point.Y * bmpData.Stride) + ((Point.X) / 8))

Let's say we're interested in the pixel at [0,0].
Point.Y == 0
bmpData.Stride == let's say 1000.
Point.X == 0
CurrentByte = Math.Truncate(0 * 1000) + (0 / 8)
CurrentByte == Math.Truncate(0)
CurrentByte == 0

Do you see a problem? You never referred to the actual pixel data, just coordinates.
To get actual pixel data you'd need
CurrentPixel = FWBitmap.GetPixel(x,y)

Now that that's clear, DON'T DO THAT. You'll still need to split CurrentPixel out into its bits and your application will be VERY SLOW.

Now, excuse my ignorance but I don't know if VB.NET has unsafecode and pointers like C# does. I assume so. You'll need to look that up. Anyone who has ever attempted to write an imaging application that handles large images has eventually realized that you need to use pointers to make it work with any kind of acceptable performance.

Hope this helps!
Share this answer
codetowns 5-Nov-11 7:23am    
Thanks for the reply Yvan. The Hex representation is new to me. Maybe I should have shown that I was looking at the CurrentByteBit of EachByte(CurrentByte) to see if it was on. The output still doesn't resemble the original for some reason though.
This is an excellent article on Lockbits and helped me when I was doing some 1bpp image processing.

One thing that tripped me up is that when you look at the array in the debugger the image is upside down!
Share this answer
codetowns 5-Nov-11 7:26am    
I have stumbled across that website before and will revisit, thanks. Interesting about the image being upside down. I assumed that point 0,0 would be the first bit in the first byte of array Eachbyte. Is that not right then?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900