Which Is The Best Image Format For VFP - Part 1
Intro
In this article, we will try to find out which is the best image format to use in VFP controls, and explain some concepts about images in general, from a VFP developer point of view.
Images in VFP
As VFP developers, we don't want to know about image formats, how images are stored, how are they displayed, etc. We just want to put an image in a button or in a form, so our applications look just as cool as any other Windows app.
One way to obtain images is to purchase image sets from any of the available online vendors. The problem with this images is that they usually are not in a format suitable for their use in VFP, since VFP is very particular about the way it handles images, and it is not without bugs in this area.
We are going to study the different image formats usually available, test them, and come up with a suitable and standard way of dealing with images in VFP.
Image formats background
Before starting, we should probably mention some facts about how images are stored and handled in Windows. An image is just a series of pixels (points), ordered in rows and columns, and each pixel has a certain value that determines its color.
The most basic type of image has only two possible values for each pixel: ON or OFF, WHITE or BLACK. For example, a 16x16 pixels image will contain 256 pixels with a possible value of 1 or 0:
1bpp image
Since each pixel can only have a value of 0 or 1, to store the color information about this image, we need just 1 bit per pixel, or, for short: 1bpp
To increase the number of available colors, we have to increase the number of bits we use to store the color information for each pixel. If instead of using 1 bit, we used 2 bits, the number of possible colors would be 4: 00, 01, 10, 11. Lets put that in a table:
| Bits | From binary | To binary | Values |
| 1bpp | 0 | 1 | 2 |
| 2bpp | 00 | 11 | 4 |
| 3bpp | 000 | 111 | 8 |
| 4bpp | 0000 | 1111 | 16 |
| 8bpp | 00000000 | 11111111 | 256 |
So, an 8bpp image can have 256 different color values, for
example a grayscale image, usually uses 8bpp, and has 256
shades of gray available to represent each pixel:

8bpp image
Another common type of image storage uses a color palette to store 256 different color values, and each pixel data is stored as an 8 bit value that references an specific color index in the palette. The advantage of this method is that less space is required to store the image data. (It is not within the scope of this article to explain the way palette based images work, please check the links at the end for more information.)
Another way of storing color information, is to use 8 bits for each RGB color channel, where RGB means Red, Green, Blue. (There are other ways to store color information besides using the RGB color space, you may want to search for CMYK, HSL)
By using 8 bits per RGB color, we need a total of 24 bits per pixel to store a color value, this format is known as 24bpp. Each pixel can have a possible color value of 256x256x256. So each pixels can have a value of 0 (black) to 16777216 (white). We could use a number to represent each possible color value, but we generally use the RGB components, like VFP does: RGB(0, 0, 0) = Black = 0, RGB(255, 255, 255) = White = 16777216
24bpp bmp image
Transparency
The problem with only storing a color value for each pixel, is that when we want to display an image, the only thing we can do is show each of the pixels with its corresponding color value, like this:
As you can see, the obvious problem is that the white "background" of the image is drawn over the button background, and the result is not pretty. With the stored image information that we have, those white pixels are just that: white, so that is the way they are drawn.
The "standard" bmp image file format has this problem, there is no way to specify if a pixel should be "transparent" or "opaque", in other words, if at the moment that Windows "draws" the bitmap pixels one by one, wether it should draw or not each pixel.
(I say the "standard" bmp format because the bmp specifications allow to store transparency information for each pixel, but no imaging program I know, or even Windows itself, seems to be capable of decoding that information.)
One way of solving this problem, is to consider one of the 16777216 available colors as "transparent" so it should not be "drawn". Most Windows developer tools use the color RGB(255,0,255) / magenta as a transparent color, so you will encounter bmp images like this:
When used in a button, this image will be drawn like this:
Image with magenta background is drawn with a transparent background, but not in Visual FoxPro.
The problems with this approach are:
- we loose one color (not a big deal, we have 16777215 left).
- the image designer and the program that uses the image should both consider the same color value as transparent.
- we only have an ON/OFF switch for transparency, so each pixel is 100% transparent or 100% opaque, no other choice.
I could not find a link that explained why magenta is a common chosen color to indicate transparency, but the fact is that VFP does not use magenta as a transparent color key, but uses white instead! So if you load the above image in a VFP commandbutton you will see this:
A magenta background bmp in a VFP commandbutton. Visual FoxPro uses White as the transparent color
Another way of specifing which pixels should be considered transparent is to use a picture mask. A picture mask is just a bmp file with its extension changed to "msk". The white pixels in the mask file correspond to transparent pixels in the image, and the black pixels correspond to opaque pixels. For example:
+
=

Yet another way to
So here we encounter our first obstacle, we have to convert all the magenta pixels to white to be able to have a bmp with transparent background in VFP. But before we go ahead an change all the pixels with a value of RGB(255,0,255) to RGB(255,255,255) we should first check if the image does not already have pixels with a color value of RGB(255,255,255) and change them to another color value.
In other words, since white is so much common than magenta in an image, before converting all the magenta pixels to white, we have to convert all the white pixels to something else, or VFP will also draw them as transparent pixels.
For example, lets see what happens if we take this image:
and change all the magenta pixels to white to make them transparent, and then we use it in a VFP commandbutton (I have pushed the button to make the problems easier to see):
As you can see, the white pixels in the image become transparent in VFP. But wait! there where already white pixels in the image! let's zoom in:
The pre-existing white pixels also became transparent! The simplest solution to this problem is to convert the pre-existing white pixels to the RGB(254,254,254) color, that is almost white, and nobody will notice the difference. (I have seen at least one available icon library that has all whites as RGB(254,254,254) already.)
This is how the image will look like, can you spot the difference between white and RGB(254,254,254)?
So if you have bmp files with a magenta background that you want to use in VFP, you have to edit them in two steps:
Convert RGB(255,255,255) to RGB(254,254,254)
Convert RGB(255,0,255) to RGB(255,255,255)
To do that easily, you can use the methods described by Cesar Chalom here:
Convert your buttons to BMPs keeping transparency with GdiPlusX
In the next part, we will continue exploring the options, until we find the best image format for VFP.
Links






bmp with no msk on the left, bmp + msk on the right