GifWriter - save frames of the screen (or memory) to an animated GIF

User projects written in or related to FreeBASIC.
Post Reply
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

GifWriter - save frames of the screen (or memory) to an animated GIF

Post by counting_pine »

I wanted to be able to record little GIF movies from FB graphics programs, but I was finding giflib a pain to work with, and not finding many good usage examples..
Then I found apparently it doesn't seem to do any attempt at frame size optimisation, which isn't ideal when outputting lots of similar frames..
So I wrote a class based on top of it for writing GIFs from FB. It can save frames directly from the Screen, and will only output changed regions on each frame.

GitHub gist: https://gist.github.com/countingpine/0f ... 33d4dbfd7f (I may convert it to a full project if I decide there is potential for significant improvement.)

Code: Select all

#include "gifwriter.bi"
'' compile with fbc example1.bas gifwriter.bas

screen 13

dim s as string = !"Hello\nWorld!"
dim g as GifWriter = GifWriter("hello.gif")
for i as integer = 1 to len(s)
	print mid(s, i, 1);
	g.saveScreen()
	sleep 100
next i
sleep
A note on optimisation currently - it will optimise the frame in ways that preserve the index values (as well as all the colour values) of all the pixels in each frame. It may not preserve the palette of each frame where changed colours are unused.

GIF image frames must all apparently either use the global palette provided at the start, or use a custom palette provided with the frame. Is far as I can gather, custom palettes can't be reused even for consecutive frames, so it's usually worth me reusing the global palette where possible, unless possibly I could reduce the bit depth by using a smaller local one. (I don't explore that.)

Also, changed regions are rectangular - no transparent pixels. Making a palette entry transparent could allow less rectangular changed regions, but would come with a lot of headaches.
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: GifWriter - save frames of the screen (or memory) to an animated GIF

Post by UEZ »

Which gif_lib.bi are you using? I cannot compile it getting errors:

gifwriter\example2.o:fake:(.text+0xda): undefined reference to `GIFWRITER::GIFWRITER(FBSTRING const&, bool)'
gifwriter\example2.o:fake:(.text+0x43e): undefined reference to `GIFWRITER::SAVEFRAME(unsigned char const*, int, int, int, unsigned int const*)@24'
gifwriter\example2.o:fake:(.text+0x4be): undefined reference to `GIFWRITER::~GIFWRITER()'
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: GifWriter - save frames of the screen (or memory) to an animated GIF

Post by counting_pine »

Those functions aren't from giflib, but are class methods implemented in gifwriter.bas. Are you compiling the example together with the class module?

PS. I'm using Linux, libgif7 version 5.1.4-2ubuntu0.1 amdb64.
__GIFLIB_VER__ is the default, i.e. 5. It probably wouldn't be hard to adapt it to 4.
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: GifWriter - save frames of the screen (or memory) to an animated GIF

Post by UEZ »

I think so,

20.05.2020 05:12 254 example1.bas
20.05.2020 05:12 750 example2.bas
20.05.2020 05:12 5.564 gifwriter.bas
20.05.2020 05:12 734 gifwriter.bi
20.05.2020 05:12 1.981 hello.gif
20.05.2020 05:12 139.131 lines.gif

When I open example2.bas and try to compile it then I'm getting the ems. But I can compile gifwriter.bas w/o any problem.

I'm on Windows10 only.

Edit: sorry, I didn't read your comment how to compile it -> compile with fbc example2.bas gifwriter.bas

Works now w/o any error message. ^^

Btw, if I change #include "gifwriter.bi" to #include "gifwriter.bas" in the example it works also directly from the IDE.
Last edited by UEZ on May 20, 2020 13:14, edited 2 times in total.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: GifWriter - save frames of the screen (or memory) to an animated GIF

Post by counting_pine »

I can't test on Windows at the moment, but it's a good sign if gifwriter.bas compiles and links by itself.
What command line are you using? You either need to compile them both at the same time, or compile gifwriter.bas to a library and link example2.bas to that.

EDIT: glad you got it sorted!
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: GifWriter - save frames of the screen (or memory) to an animated GIF

Post by UEZ »

Well done, works pretty good and might be useful one day...

Thanks for sharing it.

Edit: maybe you can add a delay to the frame not to run too fast (e.g. example 1). It should be in the graphic control extension block:

Graphics Control Extension (starts with bytes &H21 and &HF9)
1 byte &H21 Extension Block Identifier
1 byte &HF9 Extension Label
1 byte &H04 Fixed value of 4 which is the length of the following block.
1 byte Packed field.
2 bytes Delay Time: Hundredths of seconds to wait.
1 byte Transparent Color Index
1 byte &H0 The block is terminated by a &H0 value.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: GifWriter - save frames of the screen (or memory) to an animated GIF

Post by counting_pine »

Yeah, frame delays would be useful, I hope to look into that.
Looks like giflib has support for that, although it looks a little more convoluted than I hoped. (That’s been my experience with most things in GIF/giflib so far..)
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: GifWriter - save frames of the screen (or memory) to an animated GIF

Post by counting_pine »

I've added the ability to set delays now, e.g. using .addDelay(10) for a 0.1sec delay (i.e. using the native "centisecond" unit).
I've wondered whether I should have some sort of function for adding "realtime" delays, which would allow videos to run at the same speed they were recorded. It feels a little like feature creep though, not sure..
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: GifWriter - save frames of the screen (or memory) to an animated GIF

Post by UEZ »

counting_pine wrote:I've added the ability to set delays now, e.g. using .addDelay(10) for a 0.1sec delay (i.e. using the native "centisecond" unit).
I've wondered whether I should have some sort of function for adding "realtime" delays, which would allow videos to run at the same speed they were recorded. It feels a little like feature creep though, not sure..
Thanks, works good now.

You can add a delay based on FPS during recording.
Post Reply