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?
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)