Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How do you set a pixel in a 1 bit index bitmap

1,420 views
Skip to first unread message

John J. Hughes II

unread,
Feb 5, 2003, 3:02:28 PM2/5/03
to
I am trying to draw a black and white bitmap but I am getting errors. Can
someone tell me what's wrong with the below code?

The first code sample gets an error of "invalid argument" for seting the
pixel.
The second code sample gets and error of "bitmap bits are locked".

I have also tried Colors.Black & Colors.White.

Thanks,
John

Code 1:
Bitmap bmp = new Bitmap(128, 64,
System.Drawing.Imaging.PixelFormat.Format1bppIndexed);
for(int x=0; x<bmp.Width; x++)
for(int y=0; x<bmp.Height; y++)
bmp.SetPixel(x, y, (Color)bmp.Palette.Entries.GetValue(0));

Code 2:
Bitmap bmp = new Bitmap(128, 64,
System.Drawing.Imaging.PixelFormat.Format1bppIndexed);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0,
bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
for(int x=0; x<bmp.Width; x++)
for(int y=0; x<bmp.Height; y++)
bmp.SetPixel(x, y, (Color)bmp.Palette.Entries.GetValue(0));
bmp.UnlockBits(bmpData);


Bob Powell

unread,
Feb 6, 2003, 8:02:31 AM2/6/03
to
Basically you're dealing with a bit array so you have to extract the correct
pixel address. The basic byte to access is found using:

index = y*stride + (x/8)

Then the bit within the byte is found by shifting a bit into the correct
position using the lower 3 bits of X as the rotation:

mask=0x80>>(x&7)

You can set or reset the bit by oring with the mask or anding with the
complement of the mask.

This demo shows how to do it. I'm going to add an article to the FAQ on this
one. Great fun. Reminds me of programming the video array on a Sinclair
Spectrum (whoops, showing my age there :-)) )

protected unsafe void SetIndexedPixel(int x,int y,BitmapData bmd, bool
pixel)

{

byte* p=(byte*)bmd.Scan0.ToPointer();

int index=y*bmd.Stride+(x>>3);

byte mask=(byte)(0x80>>(x&0x7));

if(pixel)

p[index]|=mask;

else

p[index]&=(byte)(mask^0xff);

}


private void Form1_Load(object sender, System.EventArgs e)

{

Bitmap bm=new Bitmap(64,64,PixelFormat.Format1bppIndexed);

BitmapData bmd=bm.LockBits(new
Rectangle(0,0,64,64),ImageLockMode.ReadWrite,PixelFormat.Format1bppIndexed);

for(double a=0;a<2*Math.PI;a+=Math.PI/50)

SetIndexedPixel((int)(32+(32*Math.Cos(a))),(int)(32+(32*Math.Sin(a))),bmd,tr
ue);

this.BackgroundImage=bm;


}


--

Check out the GDI+ FAQ
http://www.bobpowell.net/gdiplus_faq.htm

"John J. Hughes II" <n...@invalid.com> wrote in message
news:O7IXdFVzCHA.2916@TK2MSFTNGP09...

John Hornick [MS]

unread,
Feb 6, 2003, 9:16:01 AM2/6/03
to
Hi,


You can't SetPixel() on an indexed-format Bitmap. You'll need to
manipulate the image bits yourself. You can do this with LockBits().

So the problem with "Code 1" is that the image 1bpp, so SetPixel()
fails.

The problem with "Code 2" is that the image bits are locked, so
SetPixel() fails before it even determines that the image is 1bpp.

You need to LockBits() then operate on the image bits at
BitmapData.Scan0 directly.

Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit http://www.microsoft.com/security for current information on security.

John J. Hughes II

unread,
Feb 6, 2003, 9:48:50 AM2/6/03
to
Thanks for the response,
John

"John Hornick [MS]" <JHor...@online.microsoft.com> wrote in message
news:THE#9oezCHA.2844@cpmsftngxa06...

John J. Hughes II

unread,
Feb 6, 2003, 9:52:53 AM2/6/03
to
Thanks for the response and the example. It helps a lot.

Don't feel too old, I started with the Atari 800.

Regards,
John


"Bob Powell" <bob@_spamkiller_bobpowell.net> wrote in message
news:#d0gu$dzCHA.428@TK2MSFTNGP09...

0 new messages