NoUserOrg

Reto Spoerri : Game Design : Zürich

ProgrammingCodeSnippletsEncodeAFolderWithImagesIntoAGifAnimation

Filed in: Resources.ProgrammingCodeSnippletsEncodeAFolderWithImagesIntoAGifAnimation · Modified on : Fri, 31 Jul 09

analyzes a given directoy and creates a list of files to be merged into a movie, which gets encoded by mplayer/mencoder.

import sys, os, re
import commands
import string

#mplayerPath = 'mplayer'
mplayerPath = 'mplayer'
mencoderPath = 'mencoder'

command = '''mplayer mf://*.png -vo gif89a:fps=10:output=output.gif'''

basedir = r'/home/_PROJECTS/_PROGRAMMING/terrain-code/terrain-implementation/keep'

def encode(filetype, outname):
  print "encoding %s to %s in %s" % (filetype, outname, os.getcwd())
  cmd = r'%s mf://%s -vo gif89a:fps=10:output=%s' % (mplayerPath, filetype, outname)
  os.system(cmd)  

def createlistfile(regexp, directory, outfile):
  print "createlistfile", regexp, directory
  regexp = re.compile(regexp)
  resultList = list()
  for file in os.listdir(directory):
    if regexp.match(file):
      resultList.append(file)
  resultList.sort()
  print resultList[0:3], "...", resultList[-4:-1]
  #for regexp.match
  f = open(outfile, 'w')
  for r in resultList:
    f.write(r+"\n")
  f.close()
  return len(resultList)

# http://www.mplayerhq.hu/DOCS/HTML/de/menc-feat-enc-images.html
formatTypes = {
'avi' : ['type=jpg', ''],
'mpng' : ['type=png', ''],
'gif' : ['gif89a', '-ovc lavc -oac copy'],
'mpg' : ['type=jpg', '-ovc lavc -oac copy vcodec=mpeg4:vbitrate=9800:mbd=2:trell of=mpeg']
}
def encodeFromFile(infilename, playSpeed, outname, format):
  print "encoding %s to %s in %s (%i fps)" % (infilename, outname, os.getcwd(), playSpeed)
  if format == 'gif':
    cmd = r'%s mf://@%s -mf fps=%i -vo gif89a:output=%s.%s' % (mplayerPath, infilename, playSpeed, outname, format)
  else:
    cmd = r'%s mf://@%s -mf fps=%i %s %s -o %s.%s' % (mencoderPath, infilename, playSpeed, formatTypes[format][0], formatTypes[format][1], outname, format)
  #  -vf scale=520:520
  print "command", cmd
  os.system(cmd)  

def inCommonRe(string1,string2):
  result = ''
  for i in xrange(min(len(string1), len(string2))):
    c1 = string1[i]
    c2 = string2[i]
    if c1 == c2:
      result += c1
    else:
      result += '.'
  return result

def inCommon(string1,string2):
  result = ''
  count = 0
  for c in string1:
    try:
      if c != string2[count]:
        break
      result += c
      count += 1
    except IndexError:
      break
  return result

def evaluateImages(dirname):
  filenames = dict()
  for fullFilename in os.listdir(dirname):
    filename, fileext = os.path.splitext(fullFilename)
    if fileext.lower() in ['.jpg','.png']:
      keyname = ''.join(re.split('[0-9]', filename))
      if keyname not in filenames.keys():
        filenames[keyname] = list()
      filenames[keyname].append(fullFilename)
  print "found filetypes", filenames.keys()

  commonNames = dict()
  for keyname, filelist in filenames.items():
    if len(filelist) > 4:
      commonName = filelist[0]
      for filename in filelist:
        commonName = inCommonRe(commonName, filename)
      commonNames[keyname] = commonName
  return commonNames

if __name__ == '__main__':
  for dirname in os.listdir(basedir):
    filepath = basedir+os.path.sep+dirname
    if os.path.isdir(filepath):
      # is a directory
      print "---", filepath, "---"
      os.chdir(filepath)

      # remove all gif files in the directory
      for fp in os.listdir(filepath):
        fn, fe = os.path.splitext(fp)
        if fe == '.gif' or fe == '.mpg' or fe == '.txt':
          print "deleting file:", fp
          os.remove(fp)


      imageNames = evaluateImages(filepath)

      for name, searchBase in imageNames.items():
        print name, searchBase

        fileListfile = name+"list.txt"

        numFiles = createlistfile(searchBase, filepath, fileListfile)
        if numFiles > 0:
          saveName = string.replace(name, '-', '-x')
          playSpeed = max(1, int(numFiles/15.))
          encodeFromFile(fileListfile, playSpeed, "anim-"+saveName, 'mpg')
          encodeFromFile(fileListfile, playSpeed, "anim-"+saveName, 'gif')

        os.remove(fileListfile)