5-Minute-Snack: Loading big images into TImage without flicker
Loading images into a TImage component is easy. We do this during design-time most of the time. In the other cases it is mostly a call to LoadFromFile and we are done.
Recently, I had the task to display several images with a timer delay. Again, very simple to implement, but if you are not careful it looks hideous. This was the piece of code I implemented in the method that was triggered whenever the next image was supposed to be shown:
myImageComponent.LoadFromFile( TImageProvider.GetNextImageFilename );
The image provider returns the filename of the next image. One would think that he last image being loaded is being shown until the next image is being displayed. Sadly, the VCL handles this differently – for good reasons, I guess.
As soon as that line is invoked, the image displayed is being removed and you end up seeing an empty space where the image has been before. Depending on the size of the image file you load that might be a significant amount of time. Even if the image has a small file size, there will always be a flicker.
A simple trick helps. Sometimes more code less compact is actually better:
var lTempStream : TMemoryStream // .... begin lTempStream := TMemoryStream.Create; try lTempStream.LoadFromFile( TImageProvider.GetNextImageFilename ); lTempStream.Position := 0; myImageComponent.Picture.LoadFromStream( lTempStream ); finally lTempStream.Free; end; //... end;
In this alternative approach, we load the image into memory first. That means the delay happens when the image is still visible. Furthermore, the assignment is instantaneous, so there will be no flicker.
Subtle difference in code, big difference in the presentation of your app.