Animated gifs

Discussions related to graphics (2D and 3D), animation and games programming
KenDown
Posts: 327
Joined: Wed 04 Apr 2018, 06:36

Animated gifs

Post by KenDown »

There has been some discussion in another forum about how to display animated gifs. The question comes from someone who appears to be even more of a newbie than me! Anyway, I thought that my routine might be of interest, especially as it allows you to specify a whole-number scale for your picture (animate gifs are usually fairly small!)

This is, of course, Richard's routine - I'm not clever enough to do all that by myself - but it shows the various installs and initialisations which it is only too easy to overlook (and which the original questioner did overlook!) The first six lines might be better placed in a PROCinit somewhere.

Code: Select all

      INSTALL @lib$+"GDIPLIB"
      INSTALL @lib$+"IMGLIB"
      PROC_gdipinit
      PROC_imgInit
      PROCinitgdiplus
      DIMrc{l%,t%,r%,b%}
      file$="H:\Trips\Cornwall\Man_engine_animation.gif 2"
      PROCanimatedgif(file$)
      END
      :
      REM Displays animated gifs
      DEFPROCanimatedgif(filename$):CLS
      LOCALwfile%,image%,ndims%,nframes%,frame%,psize%,xsize%,ysize%
      LOCALxpos%,ypos%,endtime%,DimensionIDs{},PropItem%,delay%

      REM Check if a scale has been specified
      i%=INSTR(filename$," "):ascale%=1
      IFi%>0ascale%=VALMID$(filename$,i%+1):filename$=LEFT$(filename$,i%-1)
      DIMwfile%LOCALLEN(filename$)*2+1

      SYS"MultiByteToWideChar",0,0,filename$,-1,wfile%,LEN(filename$)+1
      SYS`GdipLoadImageFromFile`,wfile%,^image%
      IFimage%=0 ERROR 100,"File not found"

      SYS`GdipImageGetFrameDimensionsCount`,image%,^ndims%
      DIMDimensionIDs{(ndims%) a%,b%,c%,d%}
      SYS`GdipImageGetFrameDimensionsList`,image%,DimensionIDs{(0)},ndims%
      SYS`GdipImageGetFrameCount`,image%,DimensionIDs{(0)},^nframes%

      PropertyTagFrameDelay%=&5100
      SYS`GdipGetPropertyItemSize`,image%,PropertyTagFrameDelay%,^psize%
      DIMPropItem%LOCALpsize%
      SYS`GdipGetPropertyItem`,image%,PropertyTagFrameDelay%,psize%,PropItem%

      SYS`GdipGetImageWidth`,image%,^xsize%
      SYS`GdipGetImageHeight`,image%,^ysize%

      SYS"GetClientRect",@hwnd%,rc{}
      tmp%=FN_gdipsetdc(@memhdc%)
      xsize%=xsize%*ascale%:ysize%=ysize%*ascale%
      REM Scale the picture to fit the window
      IFxsize%>rc.r%ysize%*=rc.r%/xsize%:xsize%=rc.r%
      IFysize%>rc.b%xsize%*=rc.b%/ysize%:ysize%=rc.b%

      xpos%=(rc.r%-xsize%)/2
      ypos%=(rc.b%-ysize%)/2
      rc.l%=xpos%:rc.r%=xpos%+xsize%
      rc.t%=ypos%:rc.b%=ypos%+ysize%

      REPEAT
        SYS`GdipImageSelectActiveFrame`,image%,DimensionIDs{(0)},frame%
        SYS`GdipDrawImageRectI`,FN_gdipg,image%,xpos%,ypos%,xsize%,ysize%
        SYS"InvalidateRect",@hwnd%,rc{},0
        delay%=PropItem%!(16+4*frame%)
        IFdelay%g%=INKEY(delay%)ELSEg%=INKEY(8)
        frame%=(frame%+1)MODnframes%
      UNTILg%=136ORg%=137

      SYS`GdipDisposeImage`,image%
      ENDPROC
      :
      REM For animated gifs
      DEFPROCinitgdiplus
      SYS"LoadLibrary","GDIPLUS.DLL"TOL@imglib%
      SYS "GetProcAddress",L@imglib%,"GdipImageGetFrameDimensionsCount" TO`GdipImageGetFrameDimensionsCount`
      SYS "GetProcAddress",L@imglib%,"GdipImageGetFrameDimensionsList"  TO`GdipImageGetFrameDimensionsList`
      SYS "GetProcAddress",L@imglib%,"GdipImageGetFrameCount"           TO`GdipImageGetFrameCount`
      SYS "GetProcAddress",L@imglib%,"GdipImageSelectActiveFrame"       TO`GdipImageSelectActiveFrame`
      SYS "GetProcAddress",L@imglib%,"GdipGetPropertyItemSize"          TO`GdipGetPropertyItemSize`
      SYS "GetProcAddress",L@imglib%,"GdipGetPropertyItem"              TO`GdipGetPropertyItem`
      SYS "GetProcAddress",L@imglib%,"GdipDrawImageRectI"               TO`GdipDrawImageRectI`
      lGDIP%=0
      ENDPROC
You will have to supply your own picture - the one I use is from a Wikipedia article about tin mining in Cornwall (https://en.wikipedia.org/wiki/Man_engine)

Note that it is sufficient to specify the picture name and path:
file$="F:\picture.gif"

The number afterwards is optional but specifies a scale, thus this gives you a picture double size.
file$="F:\picture.gif 2"
DDRM

Re: Animated gifs

Post by DDRM »

It might be of interest that Richard has posted an updated version of IMGLIB, specifically to handle animated GIFs: it is announced here:

https://groups.io/g/bb4w/topic/file_lib ... 4640019155

I think you will need to be a member of the groups.io group (which is free) to see or download it. I've asked Richard for permission to post it here as an attachment, but not yet heard back from him.

Best wishes,

D
KenDown
Posts: 327
Joined: Wed 04 Apr 2018, 06:36

Re: Animated gifs

Post by KenDown »

Yes, I have downloaded the IMGLIB library and, as you say, it does have two PROCs for dealing with animated gifs. Unfortunately there doesn't seem to be any documentation and I haven't had time to try and disect what each one does. Anyway, I thought the scaling was a nice touch with my routine.

I am sure Richard's will work faster and better and probably scaling is possible if you can work it all out.