Lazy Foo' Productions


What is a Pixel?

Last Updated: Dec 15th, 2009

As you probably know images are made out of pixels, but what are pixels made out of?
            //Map the color key
            Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF );
Here we have a line of code from the color keying tutorial. I say SDL_MapRGB() returns a pixel but how is a "Uint32" a pixel?

Uint32 is a:

Unsigned
integer that is
32 bits in size.

Now how can a number be a pixel? Well odds are you know some HTML and you know you set your colors by combining 3 numbers from 0 to 255.

<span style="color: rgb(Red,Green,Blue)">Text</span>

Above you see the HTML/CSS code I use here to change the text's color. Combining Red, Green, and Blue values can get you any color your computer can show you. For example:

This is made with Red 255, Green 255, and Blue 255.
This is made with Red 255, Green 0, and Blue 0.
This is made with Red 0, Green 0, and Blue 255.
This is made with Red 0, Green 0, and Blue 0.
This is made with Red 192, Green 192, and Blue 0.
This is made with Red 0, Green 255, and Blue 255.
This is made with Red 192, Green 128, and Blue 64.
This is made with Red 186, Green 3, and Blue 207.

I'm sure you get the picture.

Well a Uint32 is only one number. If pixels are made by a set of numbers shouldn't it be an array?

Actually, it is.

The red, green, and blue values that make up a pixel can be a number from 0 to 255. Remember 0 is a number too and in programming we always start counting from 0. That means there's up to 256 values you can have. 256 is 2 to the 8th power so that means each of the values that make up the color can be represented by 8 bit numbers.

A Uint32 is just all those bits stuck together one after the other into one number. In memory your pixel essentially looks like this:
101010110010101101011011

Since it's just an array of 8 bit numbers, all you have to do to get the individual colors is type cast from one big 32 bit number to an array of 8 bit numbers.

//Get the address of the pixel
Uint8 *colors = (Uint8*)&pixel;

//Get the individual colors
red = colors[ 0 ];
green = colors[ 1 ];
blue = colors[ 2 ];
But you should generally never do this. To get the individual colors of a pixel you should use SDL_GetRGB(). I'll tell you why in a little bit.

There's probably something bugging you right now. 8 bits per color * 3 colors = 24 bits. What are the last 8 bits? Those last 8 bits make up the alpha of the pixel.

Alpha controls the transparency of the pixel. 255 means the pixel is completely opaque and 0 means it's completely transparent. Here are some examples of an image blitted on a white background. Each time the image has a different alpha value.

Here the alpha is 255 so the image just displays normally.
255

Here the alpha is 192. You can see that the white background is starting to show through.
192

Here the alpha is 128. This is about 50% transparency.
128

Here the alpha is 0 and the image is completely invisible.
0


So that's what a 32 bit RGBA pixel is made out of, but not all pixels are built the same.

There are different pixel formats. The colors can be in different order, like BGRA has it's colors in blue, green, red, alpha. ABGR is pretty much the same thing only the alpha is the first byte. Pixels can also have different sizes, like a 24 bit BGR bitmap. There's also 16 bit color which can have 5 bits red, 5 bits green, 5 bits blue, and 1 bit alpha.

There's many more formats out there and I won't go into detail, but having all these pixel formats is why you have to pass a SDL_PixelFormat to SDL_MapRGB() and SDL_GetRGB() so the functions know how work with pixels. It's also why it's not a good idea to mess with the bytes directly unless you know for sure which pixel format you're going to get.

The different formats is also why you can't blit two surfaces of a different format together. If you copy ABGR pixels into a RGBA surface the colors are going to be all wrong. SDL can convert the pixels on the fly, but pixel conversion eats up CPU. This is why all surfaces are converted to the screen's format when we load them in our load_image() function.

There's much more to pixels like how pixel conversion works, but that's something you don't bother with unless you're working at a really low level. For now, you know all the basics about the building blocks of images.

Just as some food for thought, because all RGB pixels are a combination of 3 numbers, isn't it possible to count through all of them to show every possible color? And if images are combinations of pixels, isn't it possible to count through every possible combination of pixels and show you every image that could possibly exist?

Trippy, aint it? =)
If you have any suggestions to improve this article, It would be great if you contacted me so I can improve this article.