0

I have following code to create bitmap using array with data*

//Here create the Bitmap to the know height, width and format
Bitmap bmp = new Bitmap( 5,7,PixelFormat.Format1bppIndexed);  
//Create a BitmapData and Lock all pixels to be written 
BitmapData bmpData = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),   
ImageLockMode.WriteOnly, bmp.PixelFormat);
//Copy the data from the byte array into BitmapData.Scan0
Marshal.Copy(data, 0, bmpData.Scan0, data.Length);     
//Unlock the pixels
bmp.UnlockBits(bmpData);
bmp.Save("BitMapIcon.bmp",ImageFormat.Bmp);

My input array (data ) :

byte[5] data = {0xff,0xff,0xff,0xff,0xff}

Question :

  1. Can array of data* for bitmap input have only valu of each pixel (in this format it is 0 and 1 ) ?
  2. Why passing array of 0xff value some of pixel are not black ?
  3. Can width size be less than 1 byte ?
1
  • Black is by convention ALWAYS 0x00, or equivalent. Commented Nov 20, 2014 at 6:50

1 Answer 1

1

You have two issues:

  • First, the default palette for the indexed format uses 0 for black and 1 for white. So your code is actually trying to initialize a white bitmap, not a black one

  • Second, and more to the point of your question, is that you are not fully initializing the bitmap. This relates to your third question: the width of the bitmap is allowed to have less than 1 byte's worth of pixels, but the bitmap data itself could require more than that for a single scan line of the bitmap.

Indeed, due to the alignment requirements of a bitmap, your bitmap's "stride" is 4 bytes. So you need 28 bytes total in order to fully initialize the bitmap.

This code will initialize the bitmap the way you want:

//Here create the Bitmap to the know height, width and format
Bitmap bmp = new Bitmap(5, 7, PixelFormat.Format1bppIndexed);
//Create a BitmapData and Lock all pixels to be written 
BitmapData bmpData = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.WriteOnly, bmp.PixelFormat);
//Copy the data from the byte array into BitmapData.Scan0
byte[] data = new byte[bmpData.Stride * bmpData.Height];

for (int i = 0; i < data.Length; i++)
{
    data[i] = 0xff;
}
Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
//Unlock the pixels
bmp.UnlockBits(bmpData);

Use 0x00 instead of 0xff if you actually wanted black pixels.

Sign up to request clarification or add additional context in comments.

4 Comments

Hi,The only thing I do not understand is if my data[] now have size 28 bytes but I want to manipulate only 5x7=35bits which index in this data array now is responible for "image view".
Each row takes 4 bytes. But only the first 5 bits matter. You could set the other 23 bits to whatever you want, it won't make a difference. They are just there as padding within the bitmap data structure. So if you want to manipulate your 5x7 image at the bit level, just work on those first five bits. All that said: if you are really always dealing with such small bitmaps, I suspect you could use the Bitmap.SetPixel() method without any trouble. It's relatively slow, but here you'll probably find it's fast enough.
Thanks. bitmap.SetPixel() is not supported in indexed forma.
Ah, right. Forgot about that. Can't draw to one either (can't get a Graphics instance). Bit-twiddling it is, then. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.