2

The goal is to have animated GIFs playing inside image components with good image quality even after resizing one of the image components.

TImage example

This is the resized TImage, very bad image quality but flawless animation:

timage example

// GIF = TGIFImage
// TImage = TImage
GIF.Animate := True;
TImage.Stretch := True;
TImage.Proportional := True;
TImage.Picture.Assign(GIF);

TImage32 example

This is a resized TImage32 from the graphics32 library, very good image quality but no animation at all, only the first frame ist visible:

graphics32 example

// GIF = TGIFImage
// TImage32 = TImage32
GIF.Animate := True;
TImage32.ScaleMode := smResize;
TImage32.BitmapAlign := baCenter;
TImage32.Bitmap.Assign(GIF);

I need to have the TImage32 component play the animation or for the TImage component to have better resampling.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
pskiebe
  • 93
  • 6
  • 1
    Resampling every frame whilst playing the animation is not a good idea. Try to consider a different strategy here, I don't know, create e.g. an in-memory GIF with resampled frames. – Victoria Mar 21 '18 at 15:15
  • Or use different GIFs for different sizes – Remy Lebeau Mar 21 '18 at 19:08
  • @RemyLebeau: Such a GIF is provided by a user, that is why I can't have different GIFs, I only get one and have to do the resizing at runtime – pskiebe Mar 22 '18 at 06:56
  • @Victoria: That is exactly my workaround at the moment, I create a stacked array of resized TImage32s after reading the filestream and animate them by changing the visibility of the individual frames with a TTask. But getting the animation right is tricky and I would like to avoid that particular can of worms – pskiebe Mar 22 '18 at 07:05

1 Answers1

0

Graphics32 is not meant to display animations (like in a GIF) out of the box. Furthermore it does not contain a native GIF decoder. The code you show relies on the internal TPicture decoder from Delphi. A conversion to TImage32 with assign will only copy the first frame and thus it will result in a still image.

In order to display animations you need further code. As mentioned in the comments it would make sense to first copy the each frame of the GIF to a TBitmap32 instance (TImage32 has too much overhead). Than you need to perform the animation. If possible this should relate to the display refresh rate or take at least the time interval since the last drawing into account.

If for example your monitor uses 60fps and your gif contains 30 frames per second than you need to display each frame for two refresh cycles. Though, this would be an easy situation.

Things will get slightly more complicated if your gif contains 29 frames per second (for example). You need to develop an algorithm to pick the right frame for the current time.

So far I have not seen any implementation of the above for Graphics32, but it's not that complicated once you know what to do.

CWBudde
  • 1,783
  • 1
  • 24
  • 28
  • Too bad there isn't a GIF decoder in Graphics32, the Delphi Tpicture decoder is doing a fine job rendering the animation but does a lousy job with the image resampling. I was somewhat successful in combining the best of both worlds with a custom Graphics32 GIF animation renderer but I ran into the timing issues you described. The animation was ether too fast or too slow, couldn't get it exactly right and performance was also an issue. – pskiebe Mar 27 '18 at 14:42
  • As mentioned above it's not really complicated, but time consuming to get all the code written as it should (i.e. without timing issues). As GR32 is an open source library it requires some contributions. – CWBudde Mar 27 '18 at 22:41
  • I forgot to mention that it might be possible to use the vampyre imaging library (see http://imaginglib.sourceforge.net) for this task. – CWBudde Mar 27 '18 at 22:42