Playing GIFs without Controls

This code demonstrates how to play GIF files without using any 3rd party controls. You should create Image1 and set the index to 0, also set the Image1(0).Tag = 0 , and create Timer1. Below is the code needed to load an animation:

  nFrames = LoadGif("C:\MyPics\Myfile.gif", Image1)
 
  If nFrames > 0 Then
'      Label1.Caption = "Frames: " & nFrames
     FrameCount = 0
     
     Timer1.Interval = CLng(Image1(0).Tag)
     Timer1.Enabled = True
 End If

Then add the following code to the form.

'General Declarations
Dim nFrames As Long
Dim FrameCount As Long

Private Sub Timer1_Timer()
  Dim i As Long
 
  If FrameCount < nFrames Then
     FrameCount = FrameCount + 1
  Else
     FrameCount = 0
     For i = 1 To nFrames
     Image1(i).Visible = False
     Next
  End If
 
  Image1(FrameCount).Visible = True
  Timer1.Interval = CLng(Image1(FrameCount).Tag)
End Sub

'The routine
Public Function LoadGif(sFile As String, aImg As Variant) As Long
  Dim hFile         As Long
  Dim sImgHeader    As String
  Dim sFileHeader   As String
  Dim sBuff         As String
  Dim sPicsBuff     As String
  Dim nImgCount     As Long
  Dim i             As Long
  Dim j             As Long
  Dim xOff          As Long
  Dim yOff          As Long
  Dim TimeWait      As Long
  Dim sGifMagic     As String
 
'magic string signifying end of
'header and end of a gif frame
  sGifMagic = Chr$(0) & Chr$(33) & Chr$(249)
   
' Unload previous Images Controls
  If aImg.Count > 1 Then
     For i = 1 To aImg.Count - 1: Unload aImg(i): Next
  End If
 
'load the gif into a string buffer
  hFile = FreeFile
   
  Open sFile For Binary Access Read As hFile
     sBuff = String(LOF(hFile), Chr(0))
     Get #hFile, , sBuff
  Close #hFile
   
'begin process of splitting the loaded
'string into individual gif images.

'Each image will be assigned to its own Image control in a control array. The
'First, separate the header information from
'the image info.
  i = 1
  nImgCount = 0
  j = InStr(1, sBuff, sGifMagic) + 1
  sFileHeader = Left(sBuff, j)
   
'A gif's first characters are "GIF"
'followed by the gif type, ie "GIF89am",
'so if this missing, its not a gif.
   If Left$(sFileHeader, 3) <> "GIF" Then
      MsgBox "This file is not a *.gif file", vbCritical
      Exit Function
   End If
   
'set pointer ahead 2 bytes from the
'end of the gif magic number
   i = j + 2
   
'if the fileheader size was greater than
'127, the info on how many individual
'frames the gif has is located within the header.
   If Len(sFileHeader) >= 127 Then
       RepeatTimes = Asc(Mid(sFileHeader, 126, 1)) + (Asc(Mid(sFileHeader, 127, 1)) * 256&)
   Else
       RepeatTimes = 0
   End If

'create a temporary file in the current directory
  hFile = FreeFile
  Open "temp.gif" For Binary As hFile
           
'split out each frame of the gif, and
'write each the frame to the temporary file.
'Then load an image control for the frame,
'and load the temp file into that control.
  Do
     
    'increment counter
     nImgCount = nImgCount + 1
     
    'locate next frame end
     j = InStr(i, sBuff, sGifMagic) + 3
       
    'another check
     If j > Len(sGifMagic) Then
       
       'pad an output string, fill with the
       'frame info, and write to disk. A header
       'needs to be added as well, to assure
       'LoadPicture recognizes it as a gif.
       'Since VB's LoadPicture command ignores
       'header info and loads animated gifs as
       'static, we can safely reuse the header
       'extracted above.
        sPicsBuff = String(Len(sFileHeader) + j - i, Chr$(0))
        sPicsBuff = sFileHeader & Mid(sBuff, i - 1, j - i)
        Put #hFile, 1, sPicsBuff
       
       'The first part of the
       'extracted data is frame info
        sImgHeader = Left(Mid(sBuff, i - 1, j - i), 16)
       
       'embedded in the frame info is a
       'field that represents the frame delay
        TimeWait = ((Asc(Mid(sImgHeader, 4, 1))) + (Asc(Mid(sImgHeader, 5, 1)) * 256&)) * 10&
           
       'assign the data.
        If nImgCount > 1 Then
       
          'if this is the second or later
          'frame, load an image control
          'for the frame
           Load aImg(nImgCount - 1)
           aImg(nImgCount - 1).ZOrder 0
           
          'the frame header also contains
          'the x and y offsets of the image
          'in relation to the first (0) image.
           xOff = Asc(Mid(sImgHeader, 9, 1)) + (Asc(Mid(sImgHeader, 10, 1)) * 256&)
           yOff = Asc(Mid(sImgHeader, 11, 1)) + (Asc(Mid(sImgHeader, 12, 1)) * 256&)
           
          'position the image controls at
          'the required position
           aImg(nImgCount - 1).Left = aImg(0).Left + (xOff * Screen.TwipsPerPixelX)
           aImg(nImgCount - 1).Top = aImg(0).Top + (yOff * Screen.TwipsPerPixelY)
           
        End If
       
          'use each control's .Tag property to
          'store the frame delay period, and
          'load the picture into the image control.
           aImg(nImgCount - 1).Tag = TimeWait
           aImg(nImgCount - 1).Picture = LoadPicture("temp.gif")
           
          'update pointer
           i = j
       End If
   
  'when the j = Instr() command above returns 0,
  '3 is added, so if j = 3 there was no more
  'data in the header. We're done.
   Loop Until j = 3
     
 'close and nuke the temp file
  Close #hFile
  Kill "temp.gif"
 
  LoadGif = aImg.Count - 1
  Exit Function
   
ErrHandler:

  MsgBox "Error No. " & Err.Number & " when reading file", vbCritical
  LoadGif = False
  On Error GoTo 0
End Function


To pause the animation simply do

Timer1.Enabled = False

and to continue playing do

Timer1.Enabled = True

You might also like...

Comments

Kym Manson Till the Roof comes off Till the Lights go out Till my Legs give out Can't shut my mouth I will not fall, my Wisdoms all.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Anyone who considers arithmetic methods of producing random digits is, of course, in a state of sin.” - John von Neumann