Script for making animated gifs
Script for making animated gifs
Mostly @Flipper77: which script did you use to make an animated gif of the pufferfish? Would you share it please?
Ivan Fomichev
Re: Script for making animated gifs
I wish I had a script to do such a thing, all I'm doing is using an online gif maker to make them using "prt sc" for each frame, which isn't an ideal way to do it, since it takes a lot of time to do it, there's one in the golly scripts thread, but I doesn't have gridlines, which is why I'm not using that.
Re: Script for making animated gifs
Would you please give a link? Adding gridlines should not be that hard.
Ivan Fomichev
Re: Script for making animated gifs
Here it is, Scorbie made it based off the perl version: viewtopic.php?f=9&t=45&start=100#p17015
Re: Script for making animated gifs
There's a URL link in the script that could help you when you're stuck.
Velcrorex's avatar seems to deal well with moving objects. Maybe he might have something too.
By the way, how did people make all those gifs in LifeWiki? A script? Is there a source?
Velcrorex's avatar seems to deal well with moving objects. Maybe he might have something too.
By the way, how did people make all those gifs in LifeWiki? A script? Is there a source?
Re: Script for making animated gifs
I took the animated gif from the lifewiki page on the loafer and resized it using an online service so the file would be small enough to use for my avatar.
-Josh Ball.
Re: Script for making animated gifs
I opted for animated SVGs for Catagolue since they're inline, scalable and efficient.
If your object fits into a 40-by-40 box (and is an oscillator or spaceship), the easiest way to retrieve it is to run canonise() and look at the corresponding object page, such as:
http://catagolue.appspot.com/object/xq7 ... 6952/b3s23
You can then click 'view source' and embed the HTML (demarcated by the svg tags) into any webpage.
I suppose I could create a Golly script to perform a similar function if necessary.
If your object fits into a 40-by-40 box (and is an oscillator or spaceship), the easiest way to retrieve it is to run canonise() and look at the corresponding object page, such as:
http://catagolue.appspot.com/object/xq7 ... 6952/b3s23
You can then click 'view source' and embed the HTML (demarcated by the svg tags) into any webpage.
I suppose I could create a Golly script to perform a similar function if necessary.
What do you do with ill crystallographers? Take them to the mono-clinic!
- Extrementhusiast
- Posts: 1966
- Joined: June 16th, 2009, 11:24 pm
- Location: USA
Re: Script for making animated gifs
Those, including mine, were made during the time that conwaylife.com had a Java applet. The applet had contained an option to save a pattern animation as a GIF.Scorbie wrote:By the way, how did people make all those gifs in LifeWiki? A script? Is there a source?
I Like My Heisenburps! (and others)
Re: Script for making animated gifs
It is actually a very nice idea. I guess, generating SVG must be easier than making animated GIFs. I will try to restyle it so than it has the same look as other uploaded patterns on LifeWiki (i. e. black-on-white with gray gridlines). Then we just need to ask Nathaniel to allow uploading of SVG on the wiki.calcyman wrote:I opted for animated SVGs for Catagolue since they're inline, scalable and efficient.
Ivan Fomichev
Re: Script for making animated gifs
And possibly our avatars.codeholic wrote:Then we just need to ask Nathaniel to allow uploading of SVG on the wiki.
On the other hand, I wonder if I could get a source code of the gif part of the java applet. Maybe we could possibly translate it into python. (Mostly because IE doesn't support SVG animation. Darn!)
Oh and one more thing. Is it possible to display the pattern animation/glider synth/rle etc on the same window of the pattern page or a small popup dialog? I think that's MUCH better than clicking a link to the rle and going back again to browse other patterns.
Re: Script for making animated gifs
I proudly present the new version of the giffer.py with support of gridlines and moving objects.
EDIT: The signs of the velocity follows the golly convention.
EDIT2: Changed the grid width to 2px and gray color to C6C6C6(LifeWiki Gray) as flipper77's suggestion.
EDIT: The signs of the velocity follows the golly convention.
EDIT2: Changed the grid width to 2px and gray color to C6C6C6(LifeWiki Gray) as flipper77's suggestion.
Code: Select all
# Runs the current selection for a given number of steps and
# creates a black and white animated GIF file.
# Based on giffer.pl, which is based on code by Tony Smith.
import golly as g
import os
import struct
rect=g.getselrect()
if len(rect)==0:
g.exit("Nothing in selection.")
[x,y,width,height]=rect
if(width>=65536 or height>=65536):
g.exit("The width or height of the GIF file must be less than 65536 pixels.")
frames = pause = cellsize = gridwidth = vx = vy = filename = "?"
gridwidth = "2"
def getparam(msg):
info = "Current parameters:\n"\
+"The number of frames: "+frames+"\n"\
+"The pause time of each frame: "+pause+"centisecs\n"\
+"The size of each cell: "+cellsize+"px\n"\
+"(The width of gridlines: "+gridwidth+"px -- fixed)\n"\
+"The speed of the pattern: "+"("+vx+","+vy+")px/frame\n"\
+"The file name: "+filename+"\n\n"
return g.getstring(info+msg, "", "Create animated GIF")
frames = getparam("Enter the number of frames.")
pause = getparam("Enter the pause time of each frame (in centisecs.)")
cellsize = getparam("Enter the size of each cell (in pixels.)")
# GridLines are 2 pixels in LifeWiki gif format.
# gridwidth = getparam("Enter the width of gridlines (in pixels, 0 to disable.)")
vx, vy = getparam("Enter the speed of the pattern (in pixels per frame.)\n ex)(-3,5)px/frame -> -3 5").split()
filename = getparam("Enter the file name. ex)out.gif")
def tryint(var, name):
try:
return int(var)
except:
g.exit(name + " is not an integer: " + var)
frames = tryint(frames, "Number of frames")
pause = tryint(pause, "Pause time")
cellsize = tryint(cellsize, "Cell Size")
gridwidth = tryint(gridwidth, "Grid Width")
vx = tryint(vx, "X velocity")
vy = tryint(vy, "Y velocity")
canvasheight = (cellsize+gridwidth)*height+gridwidth
canvaswidth = (cellsize+gridwidth)*width+gridwidth
if(canvaswidth>=65536 or canvasheight>=65536):
g.exit("The width or height of the GIF file must be less than 65536 pixels."
+ "Width: " + canvaswidth + "Height: " + canvasheight)
# ------------------------------------------------------------------------------
def getpx(xrel, yrel, frameidx):
xabs = xrel + vx * frameidx
yabs = yrel + vy * frameidx
if(xabs%(cellsize+gridwidth)<gridwidth or yabs%(cellsize+gridwidth)<gridwidth):
return "2"
else: return str(g.getcell(x+xabs/(cellsize+gridwidth), y+yabs/(cellsize+gridwidth)))
def getdata(frameidx):
lines = []
# Each array element is a line of 0 and 1 characters
for ypx in xrange(canvasheight):
line = ""
for xpx in xrange(canvaswidth):
line += getpx(xpx, ypx, frameidx)
lines += line
return lines
# ------------------------------------------------------------------------------
def compress(lines):
table = {'0': 0, '1': 1, '2': 2, '3': 3}
curr = cc = 4
used = eoi = 5
bits = size = 3
mask = 7
output = code = ""
for line in lines:
for i in xrange(len(line)):
next = line[i]
if (code + next) in table:
code += next
else:
used += 1
table[(code + next)] = used
curr += table[code] << bits
bits += size
while(bits >= 8):
output += chr(curr & 255)
curr >>= 8
bits -= 8
if(used > mask):
if(size < 12):
size += 1
mask = mask*2 + 1
else:
curr += cc << bits # output cc in current width
bits += size
while(bits >= 8):
output += chr(curr & 255)
curr >>= 8
bits -= 8
table = {'0': 0, '1': 1} #reset table
used = 5
bits = 3
mask = 7
code = next
curr += table[code] << bits
bits += size
while(bits >= 8):
output += chr(curr & 255)
curr >>= 8
bits -= 8
output += chr(curr)
subbed = ""
while(len(output) > 255):
subbed += chr(255) + output[:255]
output = output[255:]
return subbed + chr(len(output)) + output + chr(0)
# ----------------------------------------------------------------------
# GIF formatting
# Useful information of GIF formats in:
# http://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp
# ----------------------------------------------------------------------
header = "GIF89a"
screendesc = struct.pack("<2HB2b", canvaswidth, canvasheight, 0x91, 0, 0)
# Colors in colortable: White, Black, LifeWiki Gray, and Black(Unused) (3 bytes each)
colortable = "\xFF\xFF\xFF\x00\x00\x00\xC6\xC6\xC6\x00\x00\x00"
applic = "\x21\xFF\x0B" + "NETSCAPE2.0" + struct.pack("<2bHb", 3, 1, 0, 0)
imagedesc = struct.pack("<4HB", 0, 0, canvaswidth, canvasheight, 0x00)
try:
gif = open(os.path.join(os.getcwd(), filename),"wb")
except:
g.exit("Unable to open file.")
gif.write(header + screendesc + colortable + applic)
for f in xrange(frames):
# Graphics control extension
gif.write("\x21\xF9" + struct.pack("<bBH2b", 4, 0x00, pause, 0, 0))
# Get data for this frame
gif.write("," + imagedesc + chr(2) + compress(getdata(f)))
g.show(str(f+1)+"/"+str(frames))
if(f+1 < frames):
g.run(1)
g.update()
gif.close()
g.show("GIF animation saved in " + filename)
- Attachments
-
- LifeWiki Syntax, 0.32s interval
I'm not sure what causes the choppy delays in chrome.
If you rightclick ->view image in new tab,
You can see that the gif works well. It's a mystery... - myosc.gif (7.36 KiB) Viewed 19206 times
- LifeWiki Syntax, 0.32s interval
Last edited by Scorbie on March 15th, 2015, 8:36 am, edited 8 times in total.
Re: Script for making animated gifs
calcyman wrote:I opted for animated SVGs for Catagolue since they're inline, scalable and efficient.
Still, I think SVG making scripts are worth publishing, because it's scalable, and because I just found out that gifs don't work so nicely on some browsers like chrome and smartphones.codeholic wrote:I will try to restyle it so than it has the same look as other uploaded patterns on LifeWiki (i. e. black-on-white with gray gridlines).
Re: Script for making animated gifs
I use chrome pretty much exclusively, and the only gifs that have trouble showing properly are the ones that have short delays between frames. Anyways, the script is great, but a few things I want to mention:Scorbie wrote: Still, I think SVG making scripts are worth publishing, because it's scalable, and because I just found out that gifs don't work so nicely on some browsers like chrome and smartphones.
- Grid lines should be 2 pixels wide with a color of #C6C6C6 to match other images on LifeWiki
- Spaceship gifs are a bit choppy with delays that fit LifeWiki's other ones
Re: Script for making animated gifs
Thanks, that seems easy enough to change.flipper77 wrote:Grid lines should be 2 pixels wide with a color of #C6C6C6 to match other images on LifeWiki
I would have to study more about gifs to figure that out. --Which might take some time.flipper77 wrote:Spaceship gifs are a bit choppy with delays that fit LifeWiki's other ones
EDIT: That's strange. When I open the gif file in my local computer -- with chrome-- there aren't any problems.
Well, I think SVGs don't have choppy delays, which is a good plus.
Re: Script for making animated gifs
Well, I've modified Scorbies script to allow for smoother spaceship gifs:
I used the code before his last edit, so you can still modify gridwidth if you like, most animations on LifeWiki have 2 pixel wide gridlines, but some look better with other options. Test it on a glider and compare to LifeWikis version to see how they compare.
EDIT: The code that wants smooth gifs is only there to show that the output gif may not be perfectly smooth, but that's hard to avoid if said gif is a spaceship type. A small bit of the code can be changed to make it better suited.
EDIT2: For some reason, the script I posted has problems with patterns with several frames, hopefully someone can find the problem.
Code: Select all
# Runs the current selection for a given number of steps and
# creates a black and white animated GIF file.
# Based on giffer.pl, which is based on code by Tony Smith.
import golly as g
import os
import struct
rect=g.getselrect()
if len(rect)==0:
g.exit("Nothing in selection.")
[x,y,width,height]=rect
if(width>=65536 or height>=65536):
g.exit("The width or height of the GIF file must be less than 65536 pixels.")
gens = pause = cellsize = gridwidth = vx = vy = fpg = filename = "?"
def getparam(msg, init = ""):
info = "Current parameters:\n"\
+"The number of gens: "+gens+"\n"\
+"The pause time of each frame: "+pause+"centisecs\n"\
+"The size of each cell: "+cellsize+"px\n"\
+"The width of gridlines: "+gridwidth+"px\n"\
+"The speed of the pattern: "+"("+vx+","+vy+")cells/frame\n"\
+"The number of frames per gen: "+fpg+" per gen\n"\
+"The file name: "+filename+"\n\n"
return g.getstring(info+msg, init, "Create animated GIF")
gens = getparam("Enter the number of gens.", "4")
pause = getparam("Enter the pause time of each frame (in centisecs.)", "50")
cellsize = getparam("Enter the size of each cell (in pixels.)", "14")
gridwidth = getparam("Enter the width of gridlines (in pixels, 0 to disable.)", "2")
vx, vy = getparam("Enter the speed of the pattern (in cells per frame.)\n ex)(-3,5)cells/frame -> -3 5", "0 0").split()
fpg = getparam("Enter the frames per gen(1 for oscillators).", "4")
filename = getparam("Enter the file name. ex)out.gif", "out.gif")
getparam("Press OK to continue.")
def tryint(var, name):
try:
return int(var)
except:
g.exit(name + " is not an integer: " + var)
gens = tryint(gens, "Number of gens")
pause = tryint(pause, "Pause time")
cellsize = tryint(cellsize, "Cell Size")
gridwidth = tryint(gridwidth, "Grid Width")
vx = tryint(vx, "X velocity")
vy = tryint(vy, "Y velocity")
fpg = tryint(fpg, "Frames/gen")
canvasheight = (cellsize+gridwidth)*height+gridwidth
canvaswidth = (cellsize+gridwidth)*width+gridwidth
if (cellsize+gridwidth)%(fpg*gens) != 0:
g.exit("%s won't be smooth: (%d + %d)/(%d * %d) isn't an integer." % (filename, cellsize, gridwidth, fpg, gens))
else:
modifier = (cellsize+gridwidth)/(fpg*gens)
if(canvaswidth>=65536 or canvasheight>=65536):
g.exit("The width or height of the GIF file must be less than 65536 pixels."
+ "Width: " + canvaswidth + "Height: " + canvasheight)
# ------------------------------------------------------------------------------
def getpx(xrel, yrel, frameidx):
xabs = xrel + vx * frameidx * modifier
yabs = yrel + vy * frameidx * modifier
if(xabs%(cellsize+gridwidth)<gridwidth or yabs%(cellsize+gridwidth)<gridwidth):
return "2"
else: return str(g.getcell(x+xabs/(cellsize+gridwidth), y+yabs/(cellsize+gridwidth)))
def getdata(frameidx):
lines = []
# Each array element is a line of 0 and 1 characters
for ypx in xrange(canvasheight):
line = ""
for xpx in xrange(canvaswidth):
line += getpx(xpx, ypx, frameidx)
lines += line
return lines
# ------------------------------------------------------------------------------
def compress(lines):
table = {'0': 0, '1': 1, '2': 2, '3': 3}
curr = cc = 4
used = eoi = 5
bits = size = 3
mask = 7
output = code = ""
for line in lines:
for i in xrange(len(line)):
next = line[i]
if (code + next) in table:
code += next
else:
used += 1
table[(code + next)] = used
curr += table[code] << bits
bits += size
while(bits >= 8):
output += chr(curr & 255)
curr >>= 8
bits -= 8
if(used > mask):
if(size < 12):
size += 1
mask = mask*2 + 1
else:
curr += cc << bits # output cc in current width
bits += size
while(bits >= 8):
output += chr(curr & 255)
curr >>= 8
bits -= 8
table = {'0': 0, '1': 1} #reset table
used = 5
bits = 3
mask = 7
code = next
curr += table[code] << bits
bits += size
while(bits >= 8):
output += chr(curr & 255)
curr >>= 8
bits -= 8
output += chr(curr)
subbed = ""
while(len(output) > 255):
subbed += chr(255) + output[:255]
output = output[255:]
return subbed + chr(len(output)) + output + chr(0)
# ----------------------------------------------------------------------
# GIF formatting
# Useful information of GIF formats in:
# http://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp
# ----------------------------------------------------------------------
header = "GIF89a"
screendesc = struct.pack("<2HB2b", canvaswidth, canvasheight, 0x91, 0, 0)
# Colors in colortable: White, Black, Gray, and Black(Unused) (3 bytes each)
colortable = "\xFF\xFF\xFF\x00\x00\x00\xC6\xC6\xC6\x00\x00\x00"
applic = "\x21\xFF\x0B" + "NETSCAPE2.0" + struct.pack("<2bHb", 3, 1, 0, 0)
imagedesc = struct.pack("<4HB", 0, 0, canvaswidth, canvasheight, 0x00)
try:
gif = open(os.path.join(os.getcwd(), filename),"wb")
except:
g.exit("Unable to open file.")
gif.write(header + screendesc + colortable + applic)
for f in xrange(gens*fpg):
# Graphics control extension
gif.write("\x21\xF9" + struct.pack("<bBH2b", 4, 0x00, pause, 0, 0))
# Get data for this frame
gif.write("," + imagedesc + chr(2) + compress(getdata(f)))
g.show(str(f+1)+"/"+str(gens*fpg))
if ((fpg == 1) | (f % fpg == fpg - 1)):
g.run(1)
g.update()
gif.close()
g.show("GIF animation saved in " + filename)
EDIT: The code that wants smooth gifs is only there to show that the output gif may not be perfectly smooth, but that's hard to avoid if said gif is a spaceship type. A small bit of the code can be changed to make it better suited.
EDIT2: For some reason, the script I posted has problems with patterns with several frames, hopefully someone can find the problem.
Re: Script for making animated gifs
After I fixed a small glitch it works pretty fine for me: https://github.com/conwaylife/giffer
Thanks to all who participated.
Thanks to all who participated.
Ivan Fomichev
Re: Script for making animated gifs
Whoopity-doo, I sniped myself a name!
Re: Script for making animated gifs
What are you doing here? Is it related to cellular automata?Namesnipe wrote:Whoopity-doo, I sniped myself a name!
Princess of Science, Parcly Taxel
Code: Select all
x = 31, y = 5, rule = B2-a/S12
3bo23bo$2obo4bo13bo4bob2o$3bo4bo13bo4bo$2bo4bobo11bobo4bo$2bo25bo!