How does one draw forms pixel by pixel?

Hello, I'm trying to figure out how to draw an image to the screen one pixel at a time. I'd like to be able to use code like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const int width = 10, height = 10;    //Picture width and height
int X = 0, Y = 0, red, blue, green;   //Pixel coordinates and RBG color

while(Y < height){                    //Loops once per pixel
  red   = GetRedForPixel(X, Y);       //The red   in this pixel
  blue  = GetBlueForPixel(X, Y);      //The blue  in this pixel
  green = GetGreenForPixel(X, Y);     //The green in this pixel

  DrawPixel(X, Y, red, blue, green);  //Draw the pixel

  if(++X == width) {                  //Move to next pixel
    X = 0;
    Y++;
  }
}


It's the "DrawPixel" function (line 9) that I'd like - something that'd let me set the color for a pixel at a specific location. I need to know how to display the pixels; I'm already good on the data structures to calculate and hold the information.

The platform is Windows 7 Pro 64-bit. The IDE is Visual Studio 2010 Premium. I would strongly prefer to use native code, but using .NET would be better than not be able to do it at all.
Last edited on
Take a look at this -> http://msdn.microsoft.com/en-us/library/dd145203%28v=VS.85%29.aspx

Check the Colors and Lines and Curves sections
With per-pixel access via WinAPI, there are a few options:

- CreateDIBSection (complicated, but extremely fast)
- GetDIBits / SetDIBits (not as complicated, still pretty fast, but not quite as fast)
- GetPixel / SetPixelV (DREADFULLY SLOW, but absurdly easy)


I don't recommend GetPixel/SetPixelV at all, as it's impractically slow. I only mentioned it here because it's likely to be the first one you find in your own research and I want to dissuade you from using it.

Generally, though, you don't draw forms pixel-by-pixel as there's no need to (forms consist of controls like buttons and text and stuff). You might have a display (like a picture box or something) that you have per-pixel access on.
Thanks, r0shi and Disch.

I'll look into CreateDIBSection; it sounds like what I'm looking for.
The CreateDIBSection documentation isn't entirely clear, but basically it works like this:

You fill out a BITMAPINFO structure with the desired specs of the bitmap you want. Generally you'd make a 32-bit bitmap with width and height as whatever you want.

The "pitch" of the bitmap is equal to width*bytes_per_pixel, and if necessary is padded up to the next 4 byte boundary (so if width*bytes was 23, the pitch would actually be 24). If you have a 32-bit bitmap, you don't need to worry about that padding.

You give CreateDIBSection that BITMAPINFO struct you filled out, as well as a pointer. It sets that pointer to point to the start of the pixel data. You can then access pixels directly via the pointer.

It'll end up looking something like this (note this is all from memory, double check all the parameters and stuff with CreateDIBSection documentation):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
BITMAPINFO info;
info.biheader.<stuff> = <stuff>;  // set 'info' accordingly

unsigned char* pixels;  // the pointer that will point to pixels

HBITMAP bmp = CreateDIBSection( ..., &info, ..., (void**)(&pixels), ... );

if(!bmp)
{
  // failed to create bitmap
}

// here, 'pixels' points to the pixel data
//   say you want to change the pixel at 100,50 to be full green:

int index = 50 * pitch;  // 'pitch' is as explained above
index += 100 * bytes_per_pixel;  // bytes per pixel is 4 for 32-bit bitmaps

pixels[index + 0] = 0;  // red (or blue, I forget)
pixels[index + 1] = 255; // green
pixels[index + 2] = 0;  // blue (or red, I forget) 


That's it. Writing to 'pixels' directly changes the pixel on the bitmap.

From there, if you want to actually display it, you put that bitmap in a DC, and BitBlt it to the display (or to another DC).
Topic archived. No new replies allowed.