setPixel

Hello,

I’m trying to draw something directly on a pixel buffer off-screen. For that I am getting the pixels of an ofImage and manipulating them directly. It should be very easy, but trying to draw a simple rectangle results in a mishmash of pixels that show misalignments. I think I’m not getting the byte size of the pixels correctly. Can someone please explain how the buffer of an image is organized. Is there an easier way to draw to a buffer off-screen. (I want it to generate procedural textures).

Thanks in advance!

  
  
void imgPattern::setPixel(int x, int y, int c) {  
  switch(myPixels.bitsPerPixel)  
  {  
    case 32:  
    case 24:  
      int* buffer = (int *)myPixels.pixels;  
      buffer[ ((y * myPixels.height) + x) ] = c;  
      break;  
  
    case 8:  
      myPixels.pixels[ ((y * myPixels.height) + x) ] = (unsigned char) (c & 0x000000ff);  
      break;  
  }  
}  
  
void imgPattern::drawRectangle(int x, int y, int w, int h, int c) {  
  for(int i = y; i < (y + h); i++) {  
    for(int j = x; j < (x + w); j++) {  
      setPixel( j, i, c);  
    }  
  }  
}  
  

in the case of 24bits you need to pass r,g,b as unsigned char or cast and mask to unsigned char as you’re doing with 8bit then:

  
buffer[ ((y * myPixels.height) + x) ] = c;  

should be:

  
buffer[ ((y * myPixels.width*3) + x*3) ] = r;  
buffer[ ((y * myPixels.width*3) + x*3 + 1) ] = g;  
buffer[ ((y * myPixels.width*3) + x*3 + 2) ] = b;  

for 8 bit:

  
myPixels.pixels[ ((y * myPixels.height) + x) ] = (unsigned char) (c & 0x000000ff);  

should be

  
myPixels.pixels[ ((y * myPixels.width) + x) ] = (unsigned char) (c & 0x000000ff);  

Woot! There was a bug in the code I pasted. The address of the pixel is not ( (y * height) + x) but ( (y * width) + x). Silly me. Thanks for pointing it out.

This also seems to work for 32bit by the way, so it might not be necessary to do three write operations for a single color:

  
  
int* buffer = (int *)myPixels.pixels;  
buffer[ ((y * myPixels.height) + x) ] = c;  
  

In this case the color is packed as follows: 0x00bbggrr, not sure how the alpha would be. I tried 0xaabbggrr and doesn’t seem to make a difference.