Accessing GIF Frames and Displaying GIF Images/Animations

External libraries (GTK, GSL, SDL, Allegro, OpenGL, etc) questions.
datwill310
Posts: 355
Joined: May 29, 2015 20:37

Accessing GIF Frames and Displaying GIF Images/Animations

Post by datwill310 »

I am having trouble finding suitable libraries (with documentation) to handle GIF images. I have found them, needless to say, but either the documentation for them is hard to understand/faulty or the they're just C libraries (and not being a C fan doesn't make this any better obviously); not knowing how to start or how to use the functions with the library.
All I need to do is:
Be able to display/play a GIF animation on a graphics screen
Be able to grab a GIF frame (and be able to use this with FB graphic functions if possible)
And features which aren't that important to me, but I could definitely see using later:
Saving images in the graphical interchange format to files on harddisk
GIF manipulation: if such things are possible; changing frames/second (time signature), edit existing GIFs ext.
Is there any FB compatible library which I can use to do these things? Any relevant advice will be accepted.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Accessing GIF Frames and Displaying GIF Images/Animation

Post by counting_pine »

Hi.
Giflib will probably do what you want. I don't know how easy it is to use, but there is an example of how to use it in FB, which you can find in the Examples directory.
https://sourceforge.net/p/fbc/code/ci/m ... oadgif.bas
datwill310
Posts: 355
Joined: May 29, 2015 20:37

Re: Accessing GIF Frames and Displaying GIF Images/Animation

Post by datwill310 »

counting_pine wrote:Hi.
Giflib will probably do what you want. I don't know how easy it is to use, but there is an example of how to use it in FB, which you can find in the Examples directory.
https://sourceforge.net/p/fbc/code/ci/m ... oadgif.bas
I have tried GIFLIB and have not found it easy to use at all. But I will try to make sense of it again, thank you.
This is partly because the documentation can't load because it has no styles associated with it.
Makoto WATANABE
Posts: 231
Joined: Apr 10, 2010 11:41
Location: Japan
Contact:

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by Makoto WATANABE »

I tried to compile the example "loadgif.bas".
FreeBASIC\examples\files\GIFLIB\loadgif.bas

1. I get a following error in FreeBASIC-Version 1.06.0.
loadgif.bas(75) error 1: Argument count mismatch in 'DGifCloseFile( ft )'

Please teach me how to fix it.
By the way, with FreeBASIC-Version 0.90.1, I could compile without the error.


2. When I run the compiled exe, I get an error "error loading .gif file".
Please teach me where to set "fblogo.gif".
I want to save "fblogo.gif" in the same folder as exe.
Please teach me how to specify the path in the program.

P.S. : I got "giflib4.dll" below.
http://gnuwin32.sourceforge.net/packages/giflib.htm
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by jj2007 »

It's all in GdiPlus. If Windows is fine for you, search for GdipImageSelectActiveFrame
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by UEZ »

Here an example how to decode GIF frames using GDIPlus windows lib -> viewtopic.php?f=7&t=27429&p=258357&hili ... r.#p258342
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by srvaldez »

hello Makoto WATANABE
first off, the binary from gnuwin32 did not work for me, so I built the libgif from source https://sourceforge.net/projects/giflib/
second, you may need to call DGifCloseFile( ft) with a second argument like this DGifCloseFile( ft , 0)
[edit]
sorry, didn't read your post carefully enough
in line 14 you can either specify the the full path of the file or if the gif will be where the executable resides, then simply set filename = "fblogo.gif"
datwill310
Posts: 355
Joined: May 29, 2015 20:37

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by datwill310 »

Jesus it's been a while.
I didn't know FB was still being worked on since dkl left :o
Makoto WATANABE
Posts: 231
Joined: Apr 10, 2010 11:41
Location: Japan
Contact:

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by Makoto WATANABE »

Dear srvaldez;
Thanks for your quick action.
I saved your "libgif" in FreeBASIC\lib\win32\libgif.a.
And, I modified the code to DGifCloseFile (ft, 0), I could view my gif file.
Image

I am always thankful to you.

Dear UEZ;
Thank you for your teaching.
I enjoyed "GDIPlus ASCII GIF Anim Player".
I simply want to see the gif animation that I registered in the exe folder.
Please introduce an example program that displays gif file as it is only once (no loop).
The thrown dice should roll.

Dear jj2007;
Thank you for teaching GDIPlus.
I will study about GDIPlus.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by UEZ »

@Makoto WATANABE: you can do something like this here using GDI+:

Code: Select all

'coded by UEZ build  2019-07-12

#Ifdef __Fb_64bit__
    #Inclib "gdiplus"
    #Include "win/gdiplus-c.bi"
#Else
    #Include "win/gdiplus.bi"
    Using gdiplus
#Endif

#Include "fbgfx.bi"

Using FB 

Dim Shared gdipToken As ULONG_PTR
Dim Shared GDIp As GdiplusStartupInput 

'decode animated GIF and select frame 
Function _GDIPlus_GIFAnimGetFrameDimensionsCount(Byval hImage As Any Ptr) As Ulong
	Dim As Ulong iFrameDimCount
	GdipImageGetFrameDimensionsCount(hImage, @iFrameDimCount)
	Return iFrameDimCount
End Function

Function _GDIPlus_GIFAnimGetFrameDimensionsList(Byval hImage As Any Ptr, Byval iFrameDimCount As Ulong) As GUID
	Dim As GUID FrameDimList
	GdipImageGetFrameDimensionsList(hImage, @FrameDimList, iFrameDimCount)
	Return FrameDimList
End Function

Function _GDIPlus_GIFAnimGetFrameCount(Byval hImage As Any Ptr, Byval tFrameDimList As GUID) As Ulong
	Dim As Ulong iFrameCount
	GdipImageGetFrameCount(hImage, @tFrameDimList, @iFrameCount)
	Return iFrameCount
End Function

Sub _GDIPlus_GIFAnimSelectActiveFrame(Byval hImage As Any Ptr, Byval tFrameDimList As GUID, Byval iCurrentFrame As Ulong)
	GdipImageSelectActiveFrame(hImage, @tFrameDimList, iCurrentFrame)
End Sub

Function _GDIPlus_ImageGetPropertyItem(Byval hImage As Any Ptr, Byval iPropID As PROPID) As PropertyItem Ptr
	Dim As Ulong iSize
	GdipGetPropertyItemSize(hImage, iPropID, @iSize)
	Dim As PropertyItem Ptr buffer
	buffer = Allocate(iSize * SizeOf(PropertyItem))
	GdipGetPropertyItem(hImage, iPropID, iSize, @buffer[0])
	Return buffer
End Function

Sub _GDIPlus_GIFAnimGetFrameDelays(Byval hImage As Any Ptr, Byval iAnimFrameCount As Ulong, aFrameDelay() As Ulong)
	Dim As PropertyItem Ptr PropItem = _GDIPlus_ImageGetPropertyItem(hImage, PROPERTYTAGFRAMEDELAY)
	Select Case PropItem->type
		Case 1
			Dim As Ubyte Ptr delay = PropItem->value
			For i As Ulong = 0 To Ubound(aFrameDelay)
				aFrameDelay(i) = delay[i] * 10
			Next
		Case 3
			Dim As Ushort Ptr delay = PropItem->value
			For i As Ulong = 0 To Ubound(aFrameDelay)
				aFrameDelay(i) = delay[i] * 10
			Next
		Case 4
			Dim As Ulong Ptr delay = PropItem->value
			For i As Ulong = 0 To Ubound(aFrameDelay)
				aFrameDelay(i) = delay[i] * 10
			Next
	End Select
End Sub
'end GDIPlus GIF section


Function _GDIPlus_Startup() As Bool
	GDIp.GdiplusVersion = 1
	If GdiplusStartup(@gdipToken, @GDIp, NULL) <> 0 Then
		Error 1
		Return False
	Endif
	Return True
End Function

Sub _GDIPlus_Shutdown()
	GdiplusShutdown(gdipToken)
End Sub

Function _GDIPlus_ImageLoadFromFile(Byval sFilename As String) As Any Ptr
	Dim GDIpImage As Any Ptr
	If (GdipLoadImageFromFile(Wstr(sFilename), @GDIpImage) <> 0) Then
		Error 1
		Return 0
	End If
	Return GDIpImage
End Function





'init GDIPlus
If _GDIPlus_Startup() = False Then End -1




Dim As String sFile = "17YK.gif" '<------- change file name here




Dim As Any Ptr hGIFAnim = _GDIPlus_ImageLoadFromFile(sFile) 'load GIG anim file

Dim As Single iW, iH

GdipGetImageDimension(hGIFAnim, @iW, @iH)	'get GIF anim dimension

If iW = 0 Then 
   GdiplusShutdown(gdipToken)
   Messagebox(0, "Something went wrong to load the GIF animation!", "ERROR", 16)
   End -2
End If

'create a FB GUI to display the animation
Screencontrol SET_DRIVER_NAME, "GDI"
Screenres iW, iH, 32, 1, GFX_HIGH_PRIORITY Or GFX_NO_SWITCH 
Dim As String sWinTitle = "GDIPlus GIF Anim Player by UEZ"

Dim As Integer iDW, iDH
Screencontrol GET_DESKTOP_SIZE, iDW, iDH
Dim tWorkingArea As RECT
SystemParametersInfo(SPI_GETWORKAREA, null, @tWorkingArea, null)
Screencontrol SET_WINDOW_POS, (iDW - iW) \ 2, ((tWorkingArea.Bottom - iH) - (iDH - tWorkingArea.Bottom)) \ 2


Dim As HWND hHWND
Screencontrol(GET_WINDOW_HANDLE, Cast(Integer, hHWND)) 'get the FB GUI handle to display GDI+ graphic handle

'create buffered GDI device to display te GIF anim
Dim As Any Ptr 	hCanvas, _
				hDC = GetDC(hHWND), _
				hHBitmap = CreateCompatibleBitmap(hDC, iW, iH), _
				hDC_backbuffer = CreateCompatibleDC(hDC), _
				hDC_obj = SelectObject(hDC_backbuffer, hHBitmap)
GdipCreateFromHDC(hDC_backbuffer, @hCanvas)	

'setup GIF animation in GDI+
Dim As Ulong iFrame = 0, iFrameDimCount = _GDIPlus_GIFAnimGetFrameDimensionsCount(hGIFAnim)
Dim As GUID tFrameDimList = _GDIPlus_GIFAnimGetFrameDimensionsList(hGIFAnim, iFrameDimCount)
Dim As Ulong iFrames = _GDIPlus_GIFAnimGetFrameCount(hGIFAnim, tFrameDimList)
Dim As Ulong aFrameDelays(0 To iFrames - 1)
_GDIPlus_GIFAnimGetFrameDelays(hGIFAnim, iFrames, aFrameDelays())

'now play animation in GUI in realtime incl. frame delays without looping
Do
	_GDIPlus_GIFAnimSelectActiveFrame(hGIFAnim, tFrameDimList, iFrame) 'extract frame
	GdipDrawImageRect(hCanvas, hGIFAnim, 0, 0, iW, iH) 'copy frame to GDI canvas
	BitBlt(hDC, 0, 0, iW, iH, hDC_backbuffer, 0, 0, SRCCOPY) 'blit frame to GUI
	Sleep aFrameDelays(iFrame)
	Windowtitle sWinTitle & " * Frame: " & iFrame + 1 & " / " & iFrames
	iFrame += 1
Loop Until iFrame = iFrames

Sleep

'release GDI / GDI+ resources
SelectObject(hDC_backbuffer, hDC_obj)
DeleteDC(hDC_backbuffer)
DeleteObject(hHBitmap)
ReleaseDC(hHWND, hDC)
GdipDeleteGraphics(hCanvas)
GdipDisposeImage(hGIFAnim)
_GDIPlus_Shutdown()

End 0

Just change the file name to the GIF animated file in line 105.
Last edited by UEZ on Jul 12, 2019 22:35, edited 1 time in total.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by srvaldez »

@UEZ
works as advertised :-)
just an observation, when compiling with -w pedantic there are a number of warnings due to missing byval or byref in your function declarations, it's easy enough to see that they should be byval, except for arrays
another thing, a normal exit is usually 0.
I hope that you are not offended by my critique :-)
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by UEZ »

srvaldez wrote:@UEZ
works as advertised :-)
just an observation, when compiling with -w pedantic there are a number of warnings due to missing byval or byref in your function declarations, it's easy enough to see that they should be byval, except for arrays
another thing, a normal exit is usually 0.
I hope that you are not offended by my critique :-)
No problem srvaldez, I'm always open for any constructive criticism. ^^

I updated the code. It should now produce no warning with -w pedantic parameter.
Makoto WATANABE
Posts: 231
Joined: Apr 10, 2010 11:41
Location: Japan
Contact:

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by Makoto WATANABE »

Dear UEZ;
Thanks for your quick reply.
Your program did what I expected.
The thrown dice rolled!

By the way, I would like to translate your program into Japanese and introduce it to Japanese people on my website.
Please consent to this.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by UEZ »

Makoto WATANABE wrote: ...
By the way, I would like to translate your program into Japanese and introduce it to Japanese people on my website.
Please consent to this.
Yes, go ahead. ^^
Bolee
Posts: 3
Joined: Jan 21, 2020 21:30

Re: Accessing GIF Frames and Displaying GIF Images/Animations

Post by Bolee »

I was wondering if an extra feature could be added to save each frame as a separate gif file?

I have some vb6 source that can do it, but was wondering if it could be done with FreeBasic?
Post Reply