I frequently need two versions of images—JPEGs for my Web site and BMPs for my magazine articles. I store the original BMP files on CDs and use a Delphi application to convert them to JPEG files. I will walk you through the code that converts BMPs to JPEGs and then converts them back to BMPs. For a little background info on graphics formats, check out this sidebar.
As of Delphi 3, the regular TImage component from the Additional tab of the Delphi component palette can display files in different formats, such as BMP, ICO, WMF/EMF, and JPEG. However, being able to display a format is not the same as being able to transform one format to another. The LoadFromFile and SaveToFile methods from the TImage component can load a BMP file, but if you save it to a file with the JPG extension, you will still get the BMP format inside.
Fortunately, Delphi 3 also added a hidden component not present on the component palette called TJPEGImage, which is declared and implemented in the JPEG unit (and the VCLJPG package). If you're looking for the source code, check out the Info\Extras\JPEG directory of your Delphi CD-ROM. (Don't tell me you never look at the Info directory of your Delphi CD—it contains many goodies.)
The TJPEGImage component is derived from TGraphic, so it's Assign-compatible with a TBitmap (also derived form TGraphic). Listing A outlines how this works. You assign an instance of a TBitmap containing a picture in BMP format to an instance of a TJPEGImage, converting the picture from BMP to JPEG along the way. Using that information, you can write a simple CONSOLE application to convert a given BMP file to a JPEG file.
Note that the TBitmap employs a LoadFromFile method that can load a file, say Handshak.bmp, into the bitmap, but you must use the SaveToStream method from the TJPEGImage to save the JPEG image to a file stream again. The latter doesn't appear to have a SaveToFile. Notice, too, that the second command-line argument is used as the compression quality percentage, which is 100 percent by default.
As an example, I converted the 44,280-byte Handshak.bmp file from the Common Files\Borland Shared\Images\Splash\256Color directory to 12 JPEG files with compression qualities of 100 percent, 95 percent, 90 percent, 85 percent, 80 percent, 75 percent, 70 percent, 65 percent, 60 percent, 55 percent, 50 percent, and 0 percent, as outlined in Table A. With 50 percent, the image was no longer good quality. The 100 percent compression quality resulted in a larger file, which for this example, occurred because Handshak.bmp is using only 256 colors. In practice, I use anything above 70 percent to get a good file size reduction (about 25 percent) while retaining a good picture. Experiment with your own BMP files to get an idea of the optimal value for the compression quality percentage.
Back to the BMP
Converting your BMP files to JPEGs can save a lot of disk space, but you do lose some of your bitmap quality. There may come a time when you want to store BMP files instead of JPEG files, if only to burn them on a CD as backup.
Fortunately, the way back from JPEG to BMP is even easier, since we don't need to specify a compression quality—unless you want to degrade the picture before converting it to a BMP, that is. But remember that a BMP file is uncompressed anyway, so setting the compression quality will have no effect on the final file size of the resulting BMP file.
The source code for the Delphi JPG2BMP project is in Listing B. The result is a file with true color and the same picture quality that was saved in the JPEG file, only it requires more disk space since it's no longer compressed.
These two code snippets offer a handy programmatic way to convert bitmaps to JPEGs and vice versa. Although you still have to consider issues of compression quality and file size, Delphi's TJPEGImage component enables you to turn the conversion into a relatively simple task.
The doctor is in
Got a question for the Delphi doctor? E-mail the editor.