3

I want to be able to transform numpy arrays into images. First, I have learned how to transform a 3D (hight x width x color) array into an image. After some research it looks to me that PIL (or Pillow) is the most natural way to do it. This is how I do it at the moment (and it works fine):

from PIL import Image
import numpy as np

if __name__ == '__main__':
    h = 4
    w = 8
    arr = np.zeros((h,w,3), dtype=np.uint8)

    arr[0, 0, :] = [255,255,0]
    arr[3, 7, :] = [0,255,0]

    img = Image.fromarray(arr, 'RGB')
    img.save('viz.png')

As a next step, I want to be able to take a list of 3D array (or a 4D array, where time is the additional dimension) and generate the corresponding animation. So, far I did not find how to do it.

It looks like Pillow is able to read gif-animation. Using ImageSequence we can access its frames. However, I cannot find out how one can put a sequence of images into animation.

I saw some solutions that use ìmages2gif but I would like to stay withing a single library.

ADDED

The answers here do not answer my question. They use gifmaker library that I cannot even install by pip.

Community
  • 1
  • 1
Roman
  • 124,451
  • 167
  • 349
  • 456
  • 1
    Possible duplicate of [Saving an animated GIF in Pillow](http://stackoverflow.com/questions/24688802/saving-an-animated-gif-in-pillow) – Reti43 Apr 04 '16 at 12:10
  • 1
    @Reti43, No, I want to do it in Pillow and the answer there uses `gifmaker`. – Roman Apr 04 '16 at 12:12
  • Which is a script from Pillow, which is a wrapper function for calling `Image.save()` with a special parameter. Does this not work for you? – Reti43 Apr 04 '16 at 12:15
  • Before I can try to use the `Image.save()` function with the `save_all=True` option I first need to figure out how to create an Image object consisting of several frames. A replacement of 3D array by a list of 3D arrays does not work. – Roman Apr 04 '16 at 12:22
  • @Reti43, I have also tried to use a 4D array instead of a list of 3D arrays. Pillow complains that there are to many dimensions. – Roman Apr 04 '16 at 12:24
  • 1
    Right, I see now. Sorry for missing out that detail. After looking around I can't find any evidence that Pillow supports what you're asking, so you'd probably have to create a modified `GifImagePlugin`, or copy the code from images2gif, save as an animated it gif and reload it to an `Image` object. I know, neither seem ideal. – Reti43 Apr 04 '16 at 12:42

1 Answers1

4

So, the main objection of the question was to generate a gif animation represented by a list of 3D arrays (frames) or by a 4D matrix (with width, height, color and time as dimension) without a use of tools that are "external" to Python.

It looks like PIL library cannot do that. At least not in a simple way without hacks or workarounds. However, the goal can be achieved by using the moviepy library. Here is the elegant solution provided by this library:

import numpy as np
import moviepy.editor as mpy

def make_frame(t):

    h = 100
    w = 100

    ar = np.zeros((h, w, 3))

    for hi in range(h):
        for wi in range(w):
            for ci in range(3):
                ar[hi, wi, ci] = 255.0*t/15.0
    return ar


if __name__ == '__main__':

    clip = mpy.VideoClip(make_frame, duration=15.0)
    clip.write_gif('ani.gif', fps=15)
Roman
  • 124,451
  • 167
  • 349
  • 456