Data returned by LockBits is incorrect

G

Guest

Hi

I need to get the color of some pixels from an image (png file). I am using
CF 2.0 and have noticed that the data returned by LockBits is not 100%
correct. For example if the pixel color is #232323. LockBits will return
#212021, if #040404 LockBits will return #000400. Is there a bug with
LockBits?

Help

Gavin
 
I

Ilya Tumanov [MS]

No, there's no bug. Bitmaps are stored in 16 bit format, so 3 LSB in red and
blue channels and 2 LSB in green are always set to zero.



Example:

#040404 = 00000100 00000100 00000100

& 11111000 11111100 11111000

= 00000000 00000100 00000000 = #000400

--
Best regards,

Ilya

This posting is provided "AS IS" with no warranties, and confers no rights.

*** Want to find answers instantly? Here's how... ***

1. Go to
http://groups-beta.google.com/group/microsoft.public.dotnet.framework.compactframework?hl=en
2. Type your question in the text box near "Search this group" button.
3. Hit "Search this group" button.
4. Read answer(s).
 
B

binaryfish

Thank Ilya but if "Bitmaps are stored in 16 bit format" what is the
purpose of Bitmap.LockBits PixelFormat parameter? Also, I tired the
code on the Framework and it worked fine so on the CF are the images
stored differently?

Regards

Gavin
 
B

binaryfish

Also your example seems to be only valid for certain colors. From your
example, if the image has magenta #FF00FF

#FF00FF = 11111111 00000000 11111111


& 11111000 11111100 11111000


= 11111000 000000 11111000 = #F800F8

But for this color LockBits it correctly returns #FF00FF
 
I

Ilya Tumanov [MS]

Let me clarify:



1. Bitmap is loaded into memory and internally stored in 16 bit format. All
LSBs are gone at this point.

2. LockBits is called; data from internal buffer is copied into another
memory area and converted to requested format.



I'm not sure why Magenta is treated differently, I suspect that's because it
commonly used as transparent color.


--
Best regards,

Ilya

This posting is provided "AS IS" with no warranties, and confers no rights.

*** Want to find answers instantly? Here's how... ***

1. Go to
http://groups-beta.google.com/group/microsoft.public.dotnet.framework.compactframework?hl=en
2. Type your question in the text box near "Search this group" button.
3. Hit "Search this group" button.
4. Read answer(s).
 
B

binaryfish

Below is some code that will create a 4 pixel bitmap with 4
differentcolors. If I use Format24bppRgb the colors returned by
LockBits are correct, but if I use Format16bppRgb565 the results are
all wrong: #FFFF00, #840000, #420000, #EF8E94. This time no transparent
color is used ;) so is it a bug?

Dim bmp As New Bitmap(4, 1,
Imaging.PixelFormat.Format16bppRgb565)
Dim gBMP As Graphics = Graphics.FromImage(bmp)
gBMP.Clear(Color.FromArgb(&HFF, &HFF, &H0))
Dim pen As New Pen(Color.FromArgb(&H40, &H0, &H0))
gBMP.DrawRectangle(pen, 1, 0, 1, 1)
pen.Color = Color.FromArgb(&H80, &H0, &H0)
gBMP.DrawRectangle(pen, 2, 0, 1, 1)
pen.Color = Color.FromArgb(&HE7, &H8F, &H91)
gBMP.DrawRectangle(pen, 3, 0, 1, 1)

Dim bmpData As System.Drawing.Imaging.BitmapData =
bmp.LockBits(New Rectangle(0, 0, 4, 1), Imaging.ImageLockMode.ReadOnly,
Imaging.PixelFormat.Format24bppRgb)
Dim ptrBMP As IntPtr = bmpData.Scan0

Dim b(4 * 1 * 3 - 1) As Byte
System.Runtime.InteropServices.Marshal.Copy(ptrBMP, b, 0,
b.Length)
bmp.UnlockBits(bmpData)

Regards

Gavin
 
S

Sergey Bogdanov

As Ilya said there is no bug here.

First of all you have to know that Bitmap represented in reverse order
and in you case each pixel has 2 bytes length. It means that:

the first 5bits - red MSBs bits
next 6bits - green MSBs bits
the last 5bits - blue MSBs bits

Try to create image 1x1 and put there Color.Magenta (0xff 0x00 0xff)
pixel, use LockBits Format16bppRgb565 to get picture bits. And you will
see the first 2 bytes:

0x1f 0xf8 - 00011111 11111000

Reverse bytes:

11111000 00011111 => 0x1f 0x00 0x1f:

Shift 0x1f on 3 bits left => 0xf7
Shift 0x0 on 2 bits left => 0x0
Shift 0x1f on 3 bits left => 0xf7

It's not easy to work with 565 pixel representation. I'd recommend you
to work with 24bpp instead - then all pixels will have 3 bytes per pixel.

And one more thing - the Bitmap has an alignment with 4 bytes - if pixel
has the length 3 bytes and you have a picture with dimension 1x2 one
byte will be added for each line. Thus instead off

Dim b(4 * 1 * 3 - 1) As Byte

you should write something like this:

Dim b(bmpData.Stride * bmpData.Height) As Byte

HTH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top