def writeAvi(filename, images, duration=0.1, encoding='mpeg4', inputOptions='', outputOptions=''): """ writeAvi(filename, duration=0.1, encoding='mpeg4', inputOptions='', outputOptions='') Export movie to a AVI file, which is encoded with the given encoding. Hint for Windows users: the 'msmpeg4v2' codec is natively supported on Windows. Images should be a list consisting of PIL images or numpy arrays. The latter should be between 0 and 255 for integer types, and between 0 and 1 for float types. Requires the "ffmpeg" application: * Most linux users can install using their package manager * There is a windows installer on the visvis website """ # Get fps try: fps = float(1.0 / duration) except Exception: raise ValueError("Invalid duration parameter for writeAvi.") # Determine temp dir and create images tempDir = os.path.join(os.path.expanduser('~'), '.tempIms') images2ims.writeIms(os.path.join(tempDir, 'im*.jpg'), images) # Determine formatter N = len(images) formatter = '%04d' if N < 10: formatter = '%d' elif N < 100: formatter = '%02d' elif N < 1000: formatter = '%03d' # Compile command to create avi command = "ffmpeg -r %i %s " % (int(fps), inputOptions) command += "-i im%s.jpg " % (formatter, ) command += "-g 1 -vcodec %s %s " % (encoding, outputOptions) command += "output.avi" # Run ffmpeg S = subprocess.Popen(command, shell=True, cwd=tempDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Show what ffmpeg has to say outPut = S.stdout.read() if S.wait(): # An error occured, show print outPut print S.stderr.read() # Clean up _cleanDir(tempDir) raise RuntimeError("Could not write avi.") else: # Copy avi shutil.copy(os.path.join(tempDir, 'output.avi'), filename) # Clean up _cleanDir(tempDir)
def writeAvi(filename, images, duration=0.1, encoding="mpeg4", inputOptions="", outputOptions=""): """ writeAvi(filename, duration=0.1, encoding='mpeg4', inputOptions='', outputOptions='') Export movie to a AVI file, which is encoded with the given encoding. Hint for Windows users: the 'msmpeg4v2' codec is natively supported on Windows. Images should be a list consisting of PIL images or numpy arrays. The latter should be between 0 and 255 for integer types, and between 0 and 1 for float types. Requires the "ffmpeg" application: * Most linux users can install using their package manager * There is a windows installer on the visvis website """ # Get fps try: fps = float(1.0 / duration) except Exception: raise ValueError("Invalid duration parameter for writeAvi.") # Determine temp dir and create images tempDir = os.path.join(os.path.expanduser("~"), ".tempIms") images2ims.writeIms(os.path.join(tempDir, "im*.jpg"), images) # Determine formatter N = len(images) formatter = "%04d" if N < 10: formatter = "%d" elif N < 100: formatter = "%02d" elif N < 1000: formatter = "%03d" # Compile command to create avi command = "ffmpeg -r %i %s " % (int(fps), inputOptions) command += "-i im%s.jpg " % (formatter,) command += "-g 1 -vcodec %s %s " % (encoding, outputOptions) command += "output.avi" # Run ffmpeg S = subprocess.Popen(command, shell=True, cwd=tempDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Show what ffmpeg has to say outPut = S.stdout.read() if S.wait(): # An error occured, show print outPut print S.stderr.read() # Clean up _cleanDir(tempDir) raise RuntimeError("Could not write avi.") else: # Copy avi shutil.copy(os.path.join(tempDir, "output.avi"), filename) # Clean up _cleanDir(tempDir)
def movieWrite(filename, images, duration=0.1, repeat=True, **kwargs): """ movieWrite(fname, images, duration=0.1, repeat=True, **kwargs) Write the movie specified in images to GIF, SWF, AVI/MPEG, or a series of images (PNG,JPG,TIF,BMP). General parameters ------------------ filename : string The name of the file to write the image to. For a series of images, the `*` wildcard can be used. images : list Should be a list consisting of PIL images or numpy arrays. The latter should be between 0 and 255 for integer types, and between 0 and 1 for float types. duration : scalar The duration for all frames. For GIF and SWF this can also be a list that specifies the duration for each frame. (For swf the durations are rounded to integer amounts of the smallest duration.) repeat : bool or integer Can be used in GIF and SWF to indicate that the movie should loop. For GIF, an integer can be given to specify the number of loops. Special GIF parameters ---------------------- dither : bool Whether to apply dithering nq : integer If nonzero, applies the NeuQuant quantization algorithm to create the color palette. This algorithm is superior, but slower than the standard PIL algorithm. The value of nq is the quality parameter. 1 represents the best quality. 10 is in general a good tradeoff between quality and speed. When using this option, better results are usually obtained when subRectangles is False. subRectangles : False, True, or a list of 2-element tuples Whether to use sub-rectangles. If True, the minimal rectangle that is required to update each frame is automatically detected. This can give significant reductions in file size, particularly if only a part of the image changes. One can also give a list of x-y coordinates if you want to do the cropping yourself. The default is True. dispose : int How to dispose each frame. 1 means that each frame is to be left in place. 2 means the background color should be restored after each frame. 3 means the decoder should restore the previous frame. If subRectangles==False, the default is 2, otherwise it is 1. Special AVI/MPEG parameters --------------------------- encoding : {'mpeg4', 'msmpeg4v2', ...} The encoding to use. Hint for Windows users: the 'msmpeg4v2' codec is natively supported on Windows. inputOptions : string See the documentation of ffmpeg outputOptions : string See the documentation of ffmpeg Notes for writing a series of images ------------------------------------ If the filenenumber contains an asterix, a sequence number is introduced at its location. Otherwise the sequence number is introduced right before the final dot. To enable easy creation of a new directory with image files, it is made sure that the full path exists. Notes for writing AVI/MPEG -------------------------- Writing AVI requires the "ffmpeg" application: * Most linux users can install it using their package manager. * There is a windows installer on the visvis website. Notes on compression and limitations ------------------------------------ * GIF: Requires PIL. Animated GIF applies a color-table of maximal 256 colors. It's widely applicable though. Reading back GIF images can be problematic due to the applied color reductions and because of problems with PIL. * SWF: Provides lossless storage of movie frames with good (ZLIB) compression. Reading of SWF files is limited to images stored using ZLIB compression. Requires no external libraries. * AVI: Requires ffmpeg. Provides excelent mpeg4 (or any other supported by ffmpeg) compression. Not intended for reading very large movies. * IMS: Requires PIL. Quality depends on the used image type. Use png for lossless compression and jpg otherwise. """ # Test images if not isinstance(images, (tuple, list)): raise ValueError("Images should be a tuple or list.") if not images: raise ValueError("List of images is empty.") # Get extension EXT = os.path.splitext(filename)[1] EXT = EXT[1:].upper() # Start timer t0 = time.time() # Write if EXT == 'GIF': writeGif(filename, images, duration, repeat, **kwargs) elif EXT == 'SWF': writeSwf(filename, images, duration, repeat, **kwargs) elif EXT in videoTypes: writeAvi(filename, images, duration, **kwargs) elif EXT in imageTypes: writeIms(filename, images, **kwargs) else: raise ValueError('Given file extension not valid: '+EXT) # Stop timer t1 = time.time() dt = t1-t0 # Notify print "Wrote %i frames to %s in %1.2f seconds (%1.0f ms/frame)" % ( len(images), EXT, dt, 1000*dt/len(images))
def movieWrite(filename, images, duration=0.1, repeat=True, **kwargs): """ movieWrite(fname, images, duration=0.1, repeat=True, **kwargs) Write the movie specified in images to GIF, SWF, AVI/MPEG, or a series of images (PNG,JPG,TIF,BMP). General parameters ------------------ filename : string The name of the file to write the image to. For a series of images, the `*` wildcard can be used. images : list Should be a list consisting of PIL images or numpy arrays. The latter should be between 0 and 255 for integer types, and between 0 and 1 for float types. duration : scalar The duration for all frames. For GIF and SWF this can also be a list that specifies the duration for each frame. (For swf the durations are rounded to integer amounts of the smallest duration.) repeat : bool or integer Can be used in GIF and SWF to indicate that the movie should loop. For GIF, an integer can be given to specify the number of loops. Special GIF parameters ---------------------- dither : bool Whether to apply dithering nq : integer If nonzero, applies the NeuQuant quantization algorithm to create the color palette. This algorithm is superior, but slower than the standard PIL algorithm. The value of nq is the quality parameter. 1 represents the best quality. 10 is in general a good tradeoff between quality and speed. When using this option, better results are usually obtained when subRectangles is False. subRectangles : False, True, or a list of 2-element tuples Whether to use sub-rectangles. If True, the minimal rectangle that is required to update each frame is automatically detected. This can give significant reductions in file size, particularly if only a part of the image changes. One can also give a list of x-y coordinates if you want to do the cropping yourself. The default is True. dispose : int How to dispose each frame. 1 means that each frame is to be left in place. 2 means the background color should be restored after each frame. 3 means the decoder should restore the previous frame. If subRectangles==False, the default is 2, otherwise it is 1. Special AVI/MPEG parameters --------------------------- encoding : {'mpeg4', 'msmpeg4v2', ...} The encoding to use. Hint for Windows users: the 'msmpeg4v2' codec is natively supported on Windows. inputOptions : string See the documentation of ffmpeg outputOptions : string See the documentation of ffmpeg Notes for writing a series of images ------------------------------------ If the filenenumber contains an asterix, a sequence number is introduced at its location. Otherwise the sequence number is introduced right before the final dot. To enable easy creation of a new directory with image files, it is made sure that the full path exists. Notes for writing AVI/MPEG -------------------------- Writing AVI requires the "ffmpeg" application: * Most linux users can install it using their package manager. * There is a windows installer on the visvis website. Notes on compression and limitations ------------------------------------ * GIF: Requires PIL. Animated GIF applies a color-table of maximal 256 colors. It's widely applicable though. Reading back GIF images can be problematic due to the applied color reductions and because of problems with PIL. * SWF: Provides lossless storage of movie frames with good (ZLIB) compression. Reading of SWF files is limited to images stored using ZLIB compression. Requires no external libraries. * AVI: Requires ffmpeg. Provides excelent mpeg4 (or any other supported by ffmpeg) compression. Not intended for reading very large movies. * IMS: Requires PIL. Quality depends on the used image type. Use png for lossless compression and jpg otherwise. """ # Test images if not isinstance(images, (tuple, list)): raise ValueError("Images should be a tuple or list.") if not images: raise ValueError("List of images is empty.") # Get extension EXT = os.path.splitext(filename)[1] EXT = EXT[1:].upper() # Start timer t0 = time.time() # Write if EXT == 'GIF': writeGif(filename, images, duration, repeat, **kwargs) elif EXT == 'SWF': writeSwf(filename, images, duration, repeat, **kwargs) elif EXT in videoTypes: writeAvi(filename, images, duration, **kwargs) elif EXT in imageTypes: writeIms(filename, images, **kwargs) else: raise ValueError('Given file extension not valid: ' + EXT) # Stop timer t1 = time.time() dt = t1 - t0 # Notify print "Wrote %i frames to %s in %1.2f seconds (%1.0f ms/frame)" % ( len(images), EXT, dt, 1000 * dt / len(images))