0

I'm using imageio in Python to read in jpg images and write them as a gif, using something resembling the code below.

import imageio

with imageio.get_writer('mygif.gif', mode='I') as writer:
    for filename in framefiles:    # iterate over names of jpg files I want to turn into gif frames
    frame = imageio.imread(filename)
    writer.append_data(frame)

I'm noticing that the image quality in the gifs I produce is quite poor; I suspect this is due to some form of compression. Is there a way to tell imageio not to use any compression? Or maybe a way to do this with opencv instead?

Frank Seidl
  • 148
  • 7
  • 1
    What happened when you tried reading the documentation? What happened when you tried putting, for example, `imageio gif quality` [into a search engine](https://duckduckgo.com/?q=imageio+gif+quality)? Why exactly do you expect it to be possible to create good quality gifs from jpg in the first place - have you seen this done? (Are you familiar with the gif format?) Why not use an actual video format? What problem are you actually trying to solve - why do you want an animated gif? – Karl Knechtel Jul 13 '21 at 17:47
  • Googling, I mostly found results for imageio in Java, where there looks to be no simple way to adjust compression. I'm making a gif because I was asked for one, but I don't see why an avi or mp4 wouldn't also suffice. I don't know much about any of these formats. – Frank Seidl Jul 13 '21 at 17:52
  • I would use other modules or external tools for this - ie. module `ffmpeg-python` or directly program `ffmpeg`, module `wand` or directly program `imagemagick` – furas Jul 13 '21 at 20:15
  • diging in source code I found that I can access some `GIFWriter` settings: `writer._writer.opt_quantizer` and `writer._writer.opt_palette_size` but I think main problem is that `gif` can display only `256 colors` so it has to emulate some colors using few dots with different collors. Other problem can make JPG files which could reduce image quality. – furas Jul 13 '21 at 21:39

1 Answers1

3

Real problem is that GIF can display only 256 colors (8-bits color) so it has to reduce 24-bits colors (RGB) to 256 colors or it has emulate more colors using dots with different colors - ditherring.


As for options:

Digging in source code I found that it can get two parameters quantizer, palettesize which can control image/animation quality. (There is also subrectangles to reduce file size)

But there are two plugins for GIF which use different modules Pillow or FreeImage and they need different value for quantizer

PIL needs integer 0, 1 or 2.

FI needs string 'wu' or 'nq' (but later it converts it to integer 0 or 1)

They also keep these values in different way so if you want get current value or change it after get_writer() then you also need different code.

You can select module with format='GIF-PIL' or format='GIF-FI'

with imageio.get_writer('mygif.gif', format='GIF-PIL', mode='I', 
                        quantizer=2, palettesize=32) as writer:
    print(writer)
    #print(dir(writer))
    #print(writer._writer)
    #print(dir(writer._writer))

    print('quantizer:', writer._writer.opt_quantizer)
    print('palette_size:', writer._writer.opt_palette_size)

    #writer._writer.opt_quantizer = 1
    #writer._writer.opt_palette_size = 256
    #print('quantizer:', writer._writer.opt_quantizer)
    #print('palette_size:', writer._writer.opt_palette_size)


with imageio.get_writer('mygif.gif', format='GIF-FI', mode='I', 
                        quantizer='nq', palettesize=32) as writer:
    print(writer)
    #print(dir(writer))

    print('quantizer:', writer._quantizer)
    print('palette_size:', writer._palettesize)

    #writer._quantizer = 1
    #writer._palettesize = 256
    #print('quantizer:', writer._quantizer)
    #print('palette_size:', writer._palettesize)

I tried to create animations with different settings but they don't look much better.

I get better result using external program ImageMagick in console/terminal

convert image*.jpg mygif.gif

but still it wasn't as good as video or static images.

You can run it in Python

os.system("convert image*.jpg mygif.gif")

subprocess.run("convert image*.jpg mygif.gif", shell=True)

Or you can try to do it with module Wand which is a wrapper on ImageMagick


Source code: GifWriter in pillowmulti.py and in freeimagemulti.py

* wu - Wu, Xiaolin, Efficient Statistical Computations for Optimal Color Quantization
* nq (neuqant) - Dekker A. H., Kohonen neural networks for optimal color quantization

Doc: GIF-PIL Static and animated gif (Pillow), GIF-FI Static and animated gif (FreeImage)

furas
  • 134,197
  • 12
  • 106
  • 148