March 30, 2014

November 25, 2019

Creating thumbnails

Some time ago during next "refactoring" on http://lastlog.it i wanted to change something with creating images thumbnails. Originally i was using Pillow. I can't say anything bad except problems with GIF animations (http://stackoverflow.com/questions/9988517/resize-gif-animation-pil-imagemagick-python). I was curious how imagemagick will work. I have made some small tests. On lastlog.it i want only resizing images and adding logo at the bottom so my tests are based only on those operations.

Images.

eshlox@eshlox:~/Downloads/images$ du -b {1,2,3,4,5,6,7,8}*
1470219 1.jpg
1784484 2.jpg
637483 3.jpeg
4601465 4.jpeg
2574772 5.jpeg
3125064 6.png
369206 7.gif # Animated GIF
1378203 8.gif # Animated GIF
eshlox@eshlox:~/Downloads/images$ du -sh {1,2,3,4,5,6,7,8}*
1.5M 1.jpg
1.8M 2.jpg
624K 3.jpeg
4.4M 4.jpeg
2.5M 5.jpeg
3.0M 6.png
364K 7.gif # Animated GIF
1.4M 8.gif # Animated GIF

I have created two small scripts for creating thumbnails.

Script 1.

import argparse
from PIL import Image
parser = argparse.ArgumentParser()
parser.add_argument('-i', type=str, dest='input')
args = parser.parse_args()
size = 800, 600
image = Image.open(args.input)
image.thumbnail(size, Image.ANTIALIAS)
image.save('pil_' + args.input, format=image.format, quality=85)

Script 2.

import argparse
from subprocess import Popen, PIPE
parser = argparse.ArgumentParser()
parser.add_argument('-i', type=str, dest='input')
args = parser.parse_args()
size = 800, 600
Popen([
'/usr/bin/convert',
args.input,
'-resize',
"800x>",
'-quality',
'85%',
'im_' + args.input
], stdout=PIPE, stderr=PIPE)

Times.

Image  | Pillow   | Imagemagick
------ | -------- | ------
1.jpeg | 0m0.172s | 0m0.031s
2.jpg  | 0m0.163s | 0m0.035s
3.jpeg | 0m0.153s | 0m0.025s
4.jpeg | 0m0.399s | 0m0.025s
5.jpeg | 0m0.185s | 0m0.053s
6.png  | 0m0.631s | 0m0.025s
7.gif  | 0m0.045s | 0m0.025s
8.gif  | 0m0.052s | 0m0.027s

Sizes.

eshlox@eshlox:~/Downloads/images$ du -b pil*
62514 pil_1.jpg
109483 pil_2.jpg
72873 pil_3.jpeg
28738 pil_4.jpeg
66020 pil_5.jpeg
827467 pil_6.png
286485 pil_7.gif # Does not work
321766 pil_8.gif # Does not work
eshlox@eshlox:~/Downloads/images$ du -b im*
61400 im_1.jpg
107962 im_2.jpg
72091 im_3.jpeg
54545 im_4.jpeg
67292 im_5.jpeg
742881 im_6.png
360580 im_7.gif # Works correctly
1361856 im_8.gif # Works correctly

Next test. Resize and add logo at the bottom of image.

Script 1.

import argparse
from PIL import Image
parser = argparse.ArgumentParser()
parser.add_argument('-i', type=str, dest='input')
args = parser.parse_args()
size = 800, 600
image = Image.open(args.input)
logo_image = Image.open('logo.jpg')
background = '#F9F9F9'
image_width, image_height = image.size
logo_width, logo_height = logo_image.size
image_new = Image.new(
"RGB",
(image_width, image_height + logo_height),
background
)
image_new.paste(image, (0, 0, image_width, image_height))
image_new.paste(
logo_image, (image_width - logo_width, image_height)
)
image_new.save(
'pil_logo_' + args.input,
format=image.format,
quality=85
)

Script 2.

import argparse
from subprocess import Popen, PIPE
parser = argparse.ArgumentParser()
parser.add_argument('-i', type=str, dest='input')
args = parser.parse_args()
size = 800, 600
background = '#F9F9F9'
Popen([
'/usr/bin/convert',
args.input,
'logo.jpg',
'-resize',
"800x>",
'-background',
background,
'-gravity',
'SouthEast',
'-quality',
'85%',
'-append',
'im_logo_' + args.input
], stdout=PIPE, stderr=PIPE)

Times.

| Image  | Pillow   | Imagemagick|
| ------ | ------   | ---------- |
| 1.jpeg | 0m0.267s | 0m0.043s   |
| 2.jpg  | 0m0.267s | 0m0.041s   |
| 3.jpeg | 0m0.267s | 0m0.028s   |
| 4.jpeg | 0m3.386s | 0m0.039s   |
| 5.jpeg | 0m1.401s | 0m0.104s   |
| 6.png  | 0m0.662s | 0m0.042s   |
| 7.gif  | 0m0.095s | 0m0.041s   |
| 8.gif  | 0m0.170s | 0m0.043s   |

In the second test Pillow is better that Imagemagick only for processing GIF animations. Imagemagick broke images but i think that it is caused by missing options in my commands.

I didn't test more cases because i don't need them now. Conclusions from my tests?

Pillow pros:

  • python (Imagemagick also has python api but i don't had time and willing for testing it)

Pillow cons:

  • need more code
  • slower
  • problems with GIF animations

Imagemagick cons:

  • subprocess (as I mentioned - I can use api python, maybe in the future i will test it)

Imagemagick pros:

  • faster
  • less code
  • can change size of GIF animations
  • images looks better after resizing and adding logo (with current options)

At the moment I will stay with Imagemagick.

© 2020 Przemysław Kołodziejczyk