Frames not disappearing in python wand

2019-03-05 18:24发布

问题:

As per hint from here, I tried to create a gif with 2 dissimilar images as below. It works, but one frame is not disappearing to show another frame. Why would this happen and how to rectify?

from wand.image import Image as Image2

with Image2() as wand:
    # Add new frames into sequance
    with Image2(blob=d2) as one:
        wand.sequence.append(one)
    with Image2(blob=d3) as two:
        wand.sequence.append(two)

    # Create progressive delay for each frame
    for cursor in range(2):
        with wand.sequence[cursor] as frame:
            frame.delay = 100
    # Set layer type
    wand.type = 'optimize'
    wand.save(filename='animated.gif')

display(Image('animated.gif'))

Current output:

回答1:

Updated answer

... I got error using that ...

Looks like hardcoded validation values does not allow this technique to be leveraged. This is a bug, and I'll submit a patch upstream.

@ -2548,7 +2548,7 @@ class BaseImage(Resource):
         .. versionadded:: 0.4.3

         """
-        if method not in ['merge', 'flatten', 'mosaic']:
+        if method not in IMAGE_LAYER_METHOD:
             raise TypeError('method must be one of: merge, flatten, mosaic')

Currently, wand doesn't implement the C-API methods MagickSetImageDispose, or MagickExtentImage which is what I believe you need. Although it's fairly easy to implement those methods, you may be stuck with rebuilding each image - frame-by-frame.

from wand.image import Image as Image2
from wand.color import Color
from wand.compat import nested

with nested(Image2(),
            Image2(filename='d2.gif'),
            Image2(filename='d3.gif')) as (wand, one, two):
    width = max(one.width, two.width)
    height = max(one.height, two.height)
    # Rebuild images with full extent of frame
    with Image2(width=width, height=height, background=Color('WHITE')) as f1:
        f1.composite(one, 0, 0)
        wand.sequence.append(f1)
    with Image2(width=width, height=height, background=Color('WHITE')) as f2:
        f2.composite(two, 0, 0)
        wand.sequence.append(f2)
    # Create progressive delay for each frame
    for cursor in range(2):
        with wand.sequence[cursor] as frame:
            frame.delay = 100
    wand.type = 'optimize'
    wand.save(filename='animated.gif')

Original answer DO NOT USE!


You want to call wand.image.Image.merge_layers method, not wand.image.Image.type property.

Try the following...

with Image2() as wand:
    # Add new frames into sequance
    with Image2(blob=d2) as one:
        wand.sequence.append(one)
    with Image2(blob=d3) as two:
        wand.sequence.append(two)

    # Create progressive delay for each frame
    for cursor in range(2):
        with wand.sequence[cursor] as frame:
            frame.delay = 100
    # Set layer type
    wand.merge_layers('optimize')  # or 'optimizeimage', or 'composite'
    wand.save(filename='animated.gif')