0

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:
img

Parthiban Rajendran
  • 430
  • 1
  • 7
  • 18

1 Answers1

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, 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')
emcconville
  • 23,800
  • 4
  • 50
  • 66
  • Thank you, but I got error using that as shown [here](https://s7.postimg.cc/vc4vdn0or/2018-05-17_16h44_18.png). I then tried all options suggested in error like merge, flatten, mosaic, but they all simply result in an image, not an animated gif. – Parthiban Rajendran May 17 '18 at 11:15
  • I think you misunderstood my question. I did not want to create a merged image (using one of methods suggested in error desc results in composite of 2 images: [here](https://s7.postimg.cc/e04irvetn/image.png)). I wanted each image to be one frame of animated gif, and animated gif taking image of largest size as its size (so it can show all images/frames). – Parthiban Rajendran May 17 '18 at 11:18
  • Great. Thank you. The updated answer works (though a minor change, d2 and d3 r blobs, not files). I wish the documentation is much more elaborate on these non implemented methods. Can you also kindly look into another similar issue [here](https://stackoverflow.com/questions/50390985/wand-creates-empty-frame-and-irregular-frame-rate) in which wand creates empty frame and irregular frame delays? – Parthiban Rajendran May 17 '18 at 14:15