1.

Solve : [Python] Add frame to gif image?

Answer»

So I have code that takes 2,000,000+/- 1,000,000 coordinates and creates images of lines between them (consecutively). I want to make these images into a gif file for easy viewing. Unfortunately, there are too many of them to load into MEMORY at once, so I am trying to create a gif with the first 2, then add on each image at the end. I've looked into creating gif's with the images2gif library. I'm running into an issue where when I write the gif, instead of adding to it, it replaces what already exists (I believe).

Code: [Select]try:
from images2gif import writeGif
from PIL import Image,ImageDraw,ImageTk
import os,sys,time,win32api
except ImportError:
print "This script requires images2gif, PIL, os, sys, time and win32api libraries."
exit()

try:
step=int(sys.argv[1])
except IndexError:
step=10

duration = 0.01

def current_seconds_time():
return int(round(time.time()))

def wGif(fil):
GLOBAL gif
global diration
images = [gif,fil]
size = (150,150)
for im in images:
im.thumbnail(size, Image.ANTIALIAS)
writeGif("gif.gif", images, duration=duration, subRectangles=True)


def findRemTime(x):
change = current_seconds_time() - startTime
persecond = 1.0 * change / x
return persecond*(len(lines)-x)

def HRMN(x):
global mn, hr, sec
sec = findRemTime(x)
mn = sec / 60
sec = int(sec % 60)
hr = int(mn / 60)
mn = int(mn % 60)

img = Image.new("RGB",(win32api.GetSystemMetrics(0)/2, win32api.GetSystemMetrics(1)/2), 'white')
img2 = Image.new("RGB",(win32api.GetSystemMetrics(0)/2, win32api.GetSystemMetrics(1)/2), 'white')


pen = ImageDraw.Draw(img)
pen2 = ImageDraw.Draw(img2)
log = open("log.txt",'r')
lines = log.readlines()
startTime = current_seconds_time()

last = lines[0].replace("\n","").split(",")
line = lines[1].replace("\n","").split(",")
pen.line((int(last[0]),int(last[1]),int(line[0]),int(line[1])),fill=128)
last = lines[0].replace("\n","").split(",")
line = lines[1].replace("\n","").split(",")
pen2.line((int(last[0]),int(last[1]),int(line[0]),int(line[1])),fill=128)
img.save("1.jpg")
img2.save("2.jpg")
gif = Image.open("1.jpg")
wGif(Image.open("2.jpg"))

os.remove("1.jpg")
os.remove("2.jpg")


hr = '?'
mn = '?'
sec = '?'
skipped = 0
gif = Image.open("gif.gif")
last = lines[2].replace("\n","").split(",")
update = 0
for x in xrange(3,len(lines),step):
update+=1
if update > 75:
update=0
hrMn(x)
try:
if hr > 0:
print "\r \r",str(x)+"/"+str(len(lines))," "+str(hr)+"hr "+str(mn)+"min",
else:
print "\r \r",str(x)+"/"+str(len(lines))," "+str(mn)+"min "+str(sec)+"sec",
line = lines[x].replace("\n","").split(",")
pen.line((int(last[0]),int(last[1]),int(line[0]),int(line[1])),fill=128) #Going to change the color later
img.save("img.jpg")
img = Image.open("img.jpg")
wGif(img)
os.remove("img.jpg")
gif = Image.open("gif.gif")
#duration+=0.005
img = Image.new("RGB",(win32api.GetSystemMetrics(0)/2, win32api.GetSystemMetrics(1)/2), 'white')
pen = ImageDraw.Draw(img)
last = line
except IOError:
skipped += 1
print "\r \rIOError:"+str(x)+" skipped:"+str(skipped)

I've attached an example of log.txt (or part of one, it's actually 20MB total)

[attachment deleted by admin to conserve space]I can not help with the code... however -
What do you mean by
Quote

a gif file for easy viewing.
For easy viewing It has to fit on a standard monitor. How many pixels would a image of two million points take?
A screen shot of this monitor takes about 64,000 bytes in 256 colors.
So my question is: Why does it take so much memory to create a GIF file?

Im trying to make a gif where you can watch where your mouse went. The points i mentioned are the points read in through a different script. When i said easy viewing, i ment that you cant really look at either the log file or make 2,000,000 jpg FILES, it just isnt a good way of doing it.For a simple graphic, you want to use GIF, not JPG. But even GIF has a structure that might not seem obvious. Have you seen this?
Project: What's In A GIF - Bit by Byte[/url
Quote
A GIF file is made up of a bunch of different "blocks" of data. The following diagram shows all of the different types of blocks and where they belong in the file. The file starts at the left and works it's way right. At each branch you may go one way or the other. The large "middle" section can be repeated as many times as needed. (Technically, it may also be omitted completely but i can't imagine what good a GIF file with no image data would be.)
Python is often used to create animated GIF files. There is a library for a simple GIF.
http://svn.effbot.org/public/pil/Scripts/gifmaker.py
Sorry I am no help with the code.
Quote
I'm running into an issue where when I write the gif, instead of adding to it, it replaces what already exists (I believe).

The Images2Gif library takes a series of images to create a GIF out of. It does not do anything special if one of those frames is a GIF image- they are treated the same. a PIL.Image instance loaded with a GIF can be seeked and different frames read, but the Images2GIF library treats it like any other image, so it will end up creating a new GIF image that comprises of the first frame of the GIF, and whatever frame you are trying to add.

Arguably I'm not even sure if Images2Gif did this it would solve your problem. If it was smart enough to see a GIF and then seek out all the frames as images to add to the new GIF, all of those frames will be in memory.

I expect you would have to manage the file yourself- find the end terminator, then the last Graphics Control Extension block (for the last frame) and insert a encoded GIF Frame at that position, which is easier said than done, really.



Discussion

No Comment Found