Welcome guest. Before posting on our computer help forum, you must register. Click here it's easy and free.

Author Topic: [Python] Add frame to gif image  (Read 7099 times)

0 Members and 1 Guest are viewing this topic.

Lemonilla

    Topic Starter


    Apprentice

  • "Too sweet"
  • Thanked: 70
  • Computer: Specs
  • Experience: Experienced
  • OS: Windows 7
[Python] Add frame to gif image
« on: April 25, 2015, 09:53:02 PM »
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]
Quote from: patio
God Bless the DOS Helpers...
Quote
If it compiles, send the files.

Geek-9pm


    Mastermind
  • Geek After Dark
  • Thanked: 1026
    • Gekk9pm bnlog
  • Certifications: List
  • Computer: Specs
  • Experience: Expert
  • OS: Windows 10
Re: [Python] Add frame to gif image
« Reply #1 on: April 25, 2015, 10:44:59 PM »
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?


Lemonilla

    Topic Starter


    Apprentice

  • "Too sweet"
  • Thanked: 70
  • Computer: Specs
  • Experience: Experienced
  • OS: Windows 7
Re: [Python] Add frame to gif image
« Reply #2 on: April 26, 2015, 07:48:56 AM »
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.
Quote from: patio
God Bless the DOS Helpers...
Quote
If it compiles, send the files.

Geek-9pm


    Mastermind
  • Geek After Dark
  • Thanked: 1026
    • Gekk9pm bnlog
  • Certifications: List
  • Computer: Specs
  • Experience: Expert
  • OS: Windows 10
Re: [Python] Add frame to gif image
« Reply #3 on: April 26, 2015, 08:25:49 AM »
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.

BC_Programmer


    Mastermind
  • Typing is no substitute for thinking.
  • Thanked: 1140
    • Yes
    • Yes
    • BC-Programming.com
  • Certifications: List
  • Computer: Specs
  • Experience: Beginner
  • OS: Windows 11
Re: [Python] Add frame to gif image
« Reply #4 on: April 26, 2015, 04:54:07 PM »
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.

I was trying to dereference Null Pointers before it was cool.