Beispiel #1
0
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)
Beispiel #2
0
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)) )
Beispiel #3
0
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)
Beispiel #4
0
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)))