Page 1 of 1

Gif animated in canvas

Posted: Mon Jan 05, 2026 4:24 pm
by minimy
Hi! Now that I'm recovered from the hangover :lol: . After a long period without sharing code, I return to the attack!
I want to share this code to use animated gifs in a canvas.
Was teste with many gifs and all work here. Tell me if not work for you, and please shar if you impreve the code.
The system use timer taked from the gif, but if is not defined '0', then use this var defaultDelay=60 ms.

I hope be interesting for you.

Note: Can work in sprites, images and textures if you change the output. Can use transparent images if you use DrawAlphaImage.

Code: Select all

UseGIFImageDecoder()
Structure gif_data: img.i:frames.i:frame.i:width.i:height.i:timer.i:output.i: List spd.f():EndStructure: Global gif.gif_data
Procedure   gifLoad(canvas, file.s="mygif.gif", defaultDelay=60)
  If FileSize(file)>0
    If IsImage(gif\img):FreeImage(gif\img):EndIf: ClearList(gif\spd())
    gif\img= LoadImage(#PB_Any,file,0)
    gif\width=  ImageWidth(gif\img): gif\height= ImageHeight(gif\img): gif\frames= ImageFrameCount(gif\img): gif\output= canvas
    For p= 0 To gif\frames-1
      SetImageFrame(gif\img,p): AddElement(gif\spd())
      gif\spd()= GetImageFrameDelay(gif\img): If gif\spd()= 0: gif\spd()= defaultDelay: EndIf
    Next p
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure
Procedure gifPlayer()
  If gif\img
    If ElapsedMilliseconds() > gif\timer
      SetImageFrame(gif\img, gif\frame)
      StartDrawing(CanvasOutput(gif\output)): DrawImage(ImageID(gif\img),0,0): StopDrawing()
      gif\frame +1: If gif\frame >= gif\frames: gif\frame= 0: EndIf
      gif\timer= ElapsedMilliseconds() + gif\spd()
    EndIf
  EndIf
EndProcedure
OpenWindow(0,0,0,500,281,"Gif animated v1.0",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
canvas= CanvasGadget(#PB_Any,0,0,WindowWidth(0),WindowHeight(0))
ok= gifLoad(canvas, "D:\_MIO\OS Multi\GIF\giphy.gif"): Debug "File loaded= "+ ok
Repeat
  ev= WindowEvent()
  Select ev
    Case #PB_Event_Gadget
      eg=EventGadget():et=EventType()
      Select eg
        Case 0
      EndSelect
    Case #PB_Event_CloseWindow
      Break
  EndSelect
  gifPlayer(): Delay(1)
ForEver

Re: Gif animated in canvas

Posted: Mon Jan 05, 2026 4:27 pm
by minimy

Re: Gif animated in canvas

Posted: Mon Jan 05, 2026 10:05 pm
by idle
thanks.

Re: Gif animated in canvas

Posted: Mon Jan 05, 2026 10:51 pm
by SPH
Ok on W11 and PB 6.30 b3 :wink:

Re: Gif animated in canvas

Posted: Tue Jan 06, 2026 6:50 pm
by Kwai chang caine
Splendid and useful code, even if i hate GIF animated :mrgreen: :lol:
Thanks a lot for sharing this super idea and splendid code 8)

Re: Gif animated in canvas

Posted: Tue Jan 06, 2026 7:02 pm
by ChrisR
Kwai chang caine wrote: Tue Jan 06, 2026 6:50 pm even if i hate GIF animated :mrgreen: :lol:
Not even a little GIF? I'm so disappointed :lol:
Thanks for sharing, minimy, that's cool 8)

Re: Gif animated in canvas

Posted: Tue Jan 06, 2026 9:06 pm
by Kwai chang caine
Not even a little GIF? I'm so disappointed
:wink: :lol:

Re: Gif animated in canvas

Posted: Fri Jan 16, 2026 10:32 am
by Jacobus
Hi minimy,
I tested the example from the PB documentation, which is less complex than yours, with several types of GIFs and they all display correctly; the window adapts to the size of the GIF used. :)

Code: Select all

; Enable the GIF decoder
UseGIFImageDecoder()
Filename$ = Path$+"\giphy.gif"  ; Indicate the location on the disk
If LoadImage(0, Filename$)
  OpenWindow(0, 500, 300, DesktopUnscaledX(ImageWidth(0)), DesktopUnscaledY(ImageHeight(0)), "GIF viewer") 
  CanvasGadget(0, 0, 0, ImageWidth(0), ImageHeight(0))  
  AddWindowTimer(0, 0, 50) ; Adjust the timeout to see the speed difference (50, 100, 500)
  Repeat
    Event = WaitWindowEvent()   
    If Event = #PB_Event_Timer
      SetImageFrame(0, Frame) 
      If StartDrawing(CanvasOutput(0))
        DrawImage(ImageID(0), 0, 0)
        StopDrawing()
      EndIf      
      Frame+1
      If Frame >= ImageFrameCount(0) ; Cycle back to first frame, to play in loop.
        Frame = 0
      EndIf
    EndIf   
  Until Event = #PB_Event_CloseWindow
Else
  Debug "Impossible to load the file: " + Filename$
EndIf