Delphi Images

Basically, images are displayed in TImage controls and stored in Image.Picture.Graphic. The important (polymorphic) methods of TPicture are (In this case, polymorphic means that the commands automatically handle the appropriate conversions for the different file types.) It also won't display some metafiles.

Getting Rid of Flicker | The Clipboard | JPEG | PNG | GIF | TIFF | Related Commands
Reading Images | Changing Images via a TMemoryStream | Using Scanlines[] to Edit a Canvas


Getting Rid of Flicker

Many times when images are changed, the display flickers. This will stop it. For other solutions, see GDI Graphics In Delphi - Four Ways To Kill Flicker and Picture Motion--Avoid The Flicker .


The Clipboard

TPicture has several methods related to reading and writing the clipboard. Unfortunately, the Delphi 5 help does not have any examples on how to use these.

Instead, you should use TClipboard.Assign and TPicture.Assign which do use the TPicture clipboard commands.

For these to work, be sure to add clipbrd to the uses clause.

For more info, see the Clipboard section of efg's Delphi Graphics: Algorithms.


Problems

With Windows, nothing is ever easy.


Icons

Supposedly, Clipboard.Assign works with TPicture and TGraphic. (Well, that's what the help file says.) However, the following generates a "Clipboard does not support icons" error. (Hey, that's not in the help.)


Monochrome Bitmaps

In addition, some bmp files crash Windows 98. (Until you use Alt-Ctrl-Del to kill the exe, you can not switch to any of the other open windows.) I was able to track this to TBitmap.SaveToClipboardFormat. It also "appears" to only be a problem with bmp files which have a 2-color (monochrome) palette, those with 16-color palettes work fine.

On a separate system (running Windows 95), I got "Invalid clipboard format" the first time this code executed. Afterwards, it simply copied a null graphic to the clipboard. (Note: Windows 98 crashes, Windows 95 simply reports an error.)

On the Windows 98 system, Circles.bmp also causes the Microsoft Paint program to crash if you select Edit / Select All.

Using Windows XP, it sort of works. Circles.bmp is monochrome - Dark Blue and Light Blue - but when you paste it, it is black and white. (Well, at least it doesn't crash.) Of course, this means that Delphi is ok, it is just another Windows design problem that users will blame on you and your code.


Fix

This should keep you out of trouble.


JPEG

The standard TImage component can display jpeg images without any changes to your code IF you add jpeg to the uses clause.

Modifying and/or creating JPEG images is a bit more complex and is covered in the separate JPEG Image page.


PNG

The standard TImage component can display PNG images without any changes to your code IF you download and install PNG Delphi by Gustavo Daud and add pngimage to the uses clause.

Locating, installing, and using this code is covered in the separate PNG Image page.


GIF

TOleGraphic provides a wrapper for OLEPRO32.DLL - a Microsoft dll that reads (and possibly writes) gif files. This code will display gif files on your form. Also see Torry's Delphi GIF Pages. TGIFImage (By Anders Melander) Integrates with TPicture to add GIF support to the TImage. (Full source code is provided.)


TIFF

Download bmp2tiff.zip and tiff2bmp.zip (freeware by Wolfgang Krug, I found them via efg).

To create a tiff file, just copy Bmp2tiff.pas to your program directory and call it via something like this


Related Commands

The following code is from the TOpenDialog.Filter example. These work on colors There are 42 "named" colors.


Reading Images

I have several applications that require working with and displaying several hundred small images. Ideally, I would like to load the images and work with them - no chance.

I have an application that displays MRI images that are stored as simple data files (2 bytes per pixel).

The following code requires about 3 seconds to load each image

By first writing to a non-displayed bitmap, this code requires only 1 second per bitmap.

Reading an *.bmp file is very fast (about 6 seconds for 155 images), however, the images are arranged as 4 x n. As a result, when the images are read, only the first 4 can be seen via the ImageList.

The problem is with how the *.bmp file was created - I loaded the 156 images into an imagelist (but only the first 74 are available using Windows 98, they are all read using Windows XP - same *.exe) and then saved them to the *.bmp file using this code.

The Delphi 5 help says
All images in an image list are contained in a single, wide bitmap in screen device format.
but, apparently, that is not true.

I tried setting the width of the bitmap object before assigning the handle - no effect. Either way, after

bm.Width= 1024 (the width of only 4 images)

Presumably, this is controlled by the AllocBy parameter.


Changing Images via a TMemoryStream

Since TImagelist failed to meet my requirements, I decided to try just using a very large bitmap 256x256x156 ... well that also failed. Apparently 83 images works - 84 images fails. The system simply runs out of resources (Windows 98).

It only takes a second to read the entire 20M file into an array. Reformatting it into a second array with RGB planes takes 20 seconds. I assume that the Trunc command is taking too long. I have experimented with several commands that convert an integer to a byte (trunc, dividing by 256, and shr which is the fastest).

Tbitmap writes to a stream as 3 bytes (RGB) per pixel. This code replaces one image with another (it is actually fairly fast). If you don't set PixelFormat to 24-bits, then the number of bytes per pixel depends on the screen resolution.

Notice how the bits are arranged


Using Scanlines[] to Edit a Canvas

According to How to Use Scanlines, using Scanline[y] is about 300 times faster than using Canvas.Pixels[x,y]. Canvas.Pixels[x,y] is just a wrapper for the windows function Windows.Pixels[Hdc,x,y].


Keeping the Same Aspect Ratio

Maintaining an image's original aspect ratio is relatively simple

Reference: efg's Computer Lab


Undocumented Data

The following useful data is not documented in the Delphi 5 help. (These should have been in the Windows SDK part of the help.) If a bitmap's height is positive, then 0,0 is at the bottom left corner of the image; if it is negative, then it is at the top left corner of the image. (or vise versa - its not documented in the help, I found this in TBitmap.GetScanLine in graphics.pas)

Also useful and undocumented in the Delphi 5 help file


Author: Robert Clemenzi
URL: http:// mc-computing.com / Languages / Delphi / Images.html