Search code examples
pythoncolorspngpython-imaging-librarygif

Python split image into frames, messes with colors


I'm working on a script that loops through a few directories, finds all the gifs in that directory, splits them into individual png frame images, and then writes them to a directory.

The actual splitting works just fine, however all frames other than the first one get messed up. Based on my research I understand some gifs rather than storing all individual frames only store what changes in between frames, I'm guessing this is one of those cases based on the outputs I'm getting.

Here is the code I'm using:

from PIL import Image
from os import listdir
import os
from os.path import isfile, join

characterDirs = ["01_mario"]
print(characterDirs)

#Loop through characterDirs
for char in characterDirs:

    #save each gif into a directory for easy access
    moves = [f for f in listdir("./media/gifs/" + char)]

    #Make a directory for that character
    os.mkdir("./media/frames/" + char)

    #Loop through all moves in the array
    for move in moves:
        print(move)
        i=0

        #Open the gif
        gif = Image.open("./media/gifs/" + char + "/" + move)

        #Make a directory for the move
        os.mkdir("./media/frames/" + char + "/" + move[0:-4])

        #Keep going until there are no remaining frames of the gif
        while True:
            try:

                #Save the frame
                gif.save("./media/frames/" + char + "/" + move[0:-4] + "/" + str(i+1) + ".png")

                #Increment to next frame
                gif.seek(gif.tell()+1)
                i +=1
            except EOFError:
                break

Here's a few frames that I'm getting:

https://ultimate-hitboxes.s3.amazonaws.com/stackoverflow/10.png

(You can change the 10 in the url to any number between 1-33 to get each broken frame)

Here's the full gif:

https://ultimate-hitboxes.s3.amazonaws.com/stackoverflow/MarioBAir.gif

Thanks in advance!


Solution

  • Try just using ImageMagick in Terminal like this:

    convert MarioBAir.gif -coalesce frame-%02d.png
    

    That will give you 33 separate frames:

    enter image description here

    Filenames are:

    -rw-r--r--     1 root  staff     30873 18 Mar 17:45 frame-00.png
    -rw-r--r--     1 root  staff     31971 18 Mar 17:45 frame-01.png
    -rw-r--r--     1 root  staff     75743 18 Mar 17:45 frame-02.png
    -rw-r--r--     1 root  staff     73075 18 Mar 17:45 frame-03.png
    -rw-r--r--     1 root  staff     34927 18 Mar 17:45 frame-04.png
    -rw-r--r--     1 root  staff     35757 18 Mar 17:45 frame-05.png
    ...
    ...
    -rw-r--r--     1 root  staff     72723 18 Mar 17:45 frame-31.png
    -rw-r--r--     1 root  staff     72103 18 Mar 17:45 frame-32.png
    

    If you use v7 ImageMagick, the command becomes:

    magick MarioBAir.gif -coalesce frame-%02d.png