RGB24 is a 24 bit color format. Every pixel is represented by 3 bytes, while every byte of this triple corresponds to one color value. The letters 'RGB' mean Red, Green and Blue, so one byte represents the red value, one byte represents the green value and the last byte represents the blue value.
Please note that the name RGB can be misleading since the first byte of a pixel does not necessarily have to represent the red value. In the Windows© environment, RGB data is typically organized in the order BGR. This means that the first byte represents the blue value, the second byte represents the green value and the third byte represents the red value of a RGB24 pixel. IC Imaging Control uses BGR order for the RGB24 pixel format. The organization of the pixels in the image buffer is from left to right and bottom up.
A video capture device, video format, FrameSnapSink, which defines the image data color format must have been setup. The following code fragments show step-by-step how to access and manipulate the pixel data of RGB24.
First of all, we have to capture an image. Otherwise, the image buffer would be empty. To do so, we start live mode and call FrameSnapSink::snapSingle.
The following code retrieves a byte pointer to the image data. We use a structure, RGB24Pixel to access the pixel's components, and reduce coordinate calculation to the level of RGB8:
struct RGB24Pixel { BYTE b; BYTE g; BYTE r; }; RGB24Pixel* pImgData = (RGB24Pixel*)pActiveBuf->getPtr();
In this example, we want to output the first (upper left hand) two pixels of the image. In a second step, we are going to manipulate the first 3 pixels. As mentioned before, the image data is stored bottom up. Therefore, pImgData points to the first pixel of the last line of the image. To get access to the first pixel of the first line of the image, the following calculation has to be performed:
// Calculate the index of the upper left pixel // Images are stored upside down in the image buffer SIZE dim = pActiveBuf->getFrameType().dim; int iOffsUpperLeft = (dim.cy - 1) * dim.cx;
At first, we retrieve the width and height of the image in terms of pixels. Then, the offset to the upper left pixel is calculated. Since every pixel is exactly 1 byte in size, we can calculate the offset as:
(Height-1) * Width
Now that we have the offset to the the first pixel, we can read it out:
printf( "\nImage buffer pixel format is MEDIASUBTYPE_RGB24\n" ); // Please note: RGB values are stored in the following order: B,G,R printf( "Pixel 1(RGB): %d %d %d\n", pImgData[iOffsUpperLeft + 0].r, //RED pImgData[iOffsUpperLeft + 0].g, //GREEN pImgData[iOffsUpperLeft + 0].b ); //BLUE printf( "Pixel 2(RGB): %d %d %d\n", pImgData[iOffsUpperLeft + 1].r, //RED pImgData[iOffsUpperLeft + 1].g, //GREEN pImgData[iOffsUpperLeft + 1].b ); //BLUE
Instead of only reading pixel data, it is, of course, possible to manipulate the data as well. The following code will set the upper left hand pixel to red and the next 2 pixels to green and blue. After this manipulation, the image is saved to a .bmp file.
// overwrite the first 3 pixels and save image to disk // Set the first pixel to RED pImgData[iOffsUpperLeft + 0].b = 0; // BLUE pImgData[iOffsUpperLeft + 0].g = 0; // GREEN pImgData[iOffsUpperLeft + 0].r = 255; // RED // Set the second pixel to GREEN pImgData[iOffsUpperLeft + 1].b = 0; // BLUE pImgData[iOffsUpperLeft + 1].g = 255; // GREEN pImgData[iOffsUpperLeft + 1].r = 0; // RED // Set the third pixel to BLUE pImgData[iOffsUpperLeft + 2].b = 255; // BLUE pImgData[iOffsUpperLeft + 2].g = 0; // GREEN pImgData[iOffsUpperLeft + 2].r = 0; // RED saveToFileBMP( *pActiveBuf, "RGB24.bmp" );
To check the result, open the saved image and take a look at the upper left hand pixels. They should look as follows: