Zadanie - utworzenie kwadratowych miniatur ze zdjęć.

Na etapie tworzenia mini-silnika do własnej galerii i wymyśliłem sobie, że chce mieć w niej miniatury kwadratowe, oczywiście wycięte ładnie ze środka. Googlając za rozwiązaniem trafiłem na implementacje zarówno z wykorzystaniem ImageMagicka jak i PIL Oba rozwiązania działają i tworzą to co mają tworzyć, z ciekawości jednak, stworzyłem bliźniacze skrypty i sprawdziłem wydajność obu rozwiązań.

Wynik

80 plików o rozmiarach 750*568

~/temp/misc/ time python generate_thumb_pil.py 
python generate_thumb_pil.py  6,02s user 0,09s system 98% cpu 6,175 total

~/temp/misc1_1/ time python generate_thumb_im.py 
python generate_thumb_im.py  11,28s user 1,50s system 119% cpu 10,650 total

100 plików o rozmiarach 2560*1920 każdy plik o wadze ok. 1,1MB

~/temp/im/ time python generate_thumb_im.py
python generate_thumb_im.py  58,80s user 9,70s system 116% cpu 58,739 total


~/temp/pil/ time python generate_thumb_pil.py
python generate_thumb_pil.py  60,22s user 1,62s system 98% cpu 1:02,73 total

100 plików o rozmiarach 2560*1920 każdy plik o wadze ok. 3,0MB

~/temp/im2/ time python generate_thumb_im.py
python generate_thumb_im.py  69,18s user 9,69s system 116% cpu 1:07,48 total

~/temp/pil2/ time python generate_thumb_pil.py
python generate_thumb_pil.py  67,58s user 1,42s system 99% cpu 1:09,69 total

O ile pierwszy wynik potwierdza test riklaunima, to dwa kolejne (pliki o znacznie większej rozdzielczości) wskazują na delikatną przewagę ImageMagicka

Skrypty

wersja z wykorzystaniem ImageMagick

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#generate thumb im by grizz - Witek Firlej http://grizz.pl

__project__      = "generate thumb im"
__author__    = "Witold Firlej (http://grizz.pl)"
__license__   = "GPL"
__copyright__ = "Witold Firlej"

import glob
import os

THUMB_SIZE = 125

for infile in glob.glob("*.jpg"):
    outfile = infile[:-4] + "_thumb.jpg"
    cmd = "convert " + infile +" -thumbnail x" + str(THUMB_SIZE*2) + " -resize \'" + str(THUMB_SIZE*2) +"x<\' -resize 50% -gravity center -crop " + str(THUMB_SIZE) + "x" + str(THUMB_SIZE) + "+0+0 +repage -format jpg -quality 91 " + outfile
#   print cmd
    os.system(cmd)

wersja z wykorzystaniem Python Imaging Library

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#generate thumb pil by grizz - Witek Firlej http://grizz.pl

__project__      = "generate thumb pil"
__author__    = "Witold Firlej (http://grizz.pl)"
__license__   = "GPL"
__copyright__ = "Witold Firlej"

import glob
import Image

THUMB_SIZE = 125, 125

for infile in glob.glob("*.jpg"):
    img = Image.open(infile)
    width, height = img.size

    if width > height:
        delta = width - height
        left = int(delta/2)
        upper = 0
        right = height + left
        lower = height
    else:
        delta = height - width
        left = 0
        upper = int(delta/2)
        right = width
        lower = width + upper

    img = img.crop((left, upper, right, lower))
    img.thumbnail(THUMB_SIZE, Image.ANTIALIAS)
    outfile = infile[:-4] + "_thumb.jpg"
    #print infile + " ==> " + outfile
    img.save(outfile, "JPEG")

Dostępne:

git clone git://github.com/grizz-pl/generatesquarethumbs.git

Wersja imagemagick jest w osobnej gałęzi, a więc po ściągnięciu:

cd generatesquarethumbs
git checkout -b imagemagick origin/imagemagick

Podsumowanie

Szybkość, szybkością, ale przejrzystość kodu to dopiero zaleta rozwiązania z użyciem PILa. W tym wypadku, tak miło się składa, ze zarówno wydajność jak i przejrzystość idą w parze. Oczywiście przy dużych plikach, PIL jest minimalnie mniej wydajny, ale dla celów galerii jaką tworzę (nie będę w niej zamieszczał plików o tak dużej rozdzielczości) jest idealny.

Efekt galerii mozna zobaczyć tutaj: http://galeria.firlej.org/

Linki

W powyższych skryptach korzystałem z rozwiązań pochodzących z:

http://www.randomsequence.com/articles/making-square-thumbnails-with-imagemagick/ http://javiergodinez.blogspot.com/2008/03/square-thumbnail-with-python-image.html


Komentarze

comments powered by Disqus