画像の回転処理にpython-jpegtranを使う

jpegtranのPythonバインディングである python-jpegtran を使ってみるところまで。

jpegtran

jpegtranは libjpeg に含まれる無劣化(lossless)で画像処理が行えるツールです。 プログレッシブJPEGへの変換や、回転、反転等が行えます。 python-jpegtranはその名の通りjpegtranのPythonバインディングです。

インストール

ソースからビルドしないとイケない。淡々と。

$ wget http://www.ijg.org/files/jpegsrc.v8c.tar.gz
$ tar xzf jpegsrc.v8c.tar.gz
$ ls
$ jpeg-8c
$ wget http://ebiznisz.hu/python-jpegtran/python-jpegtran-0.1.tgz
$ tar xzf python-jpegtran-0.1.tgz
$ cd python-jpegtran-0.1
$ vim Makefile      # 下記のdiff参照

--- Makefile.org    2006-10-30 04:53:50.000000000 +0900
+++ Makefile    2011-04-20 23:45:46.074106002 +0900
@@ -3,8 +3,8 @@
 # JPEG_SRC should point to the source installation of jpegtran
 # PYTHON_INCLUDE should point to the include directory of python

-JPEG_SRC = /home/nogradi/tmp/jpeg-6b
-PYTHON_INCLUDE = /usr/include/python2.3
+JPEG_SRC = ../jpeg-8c
+PYTHON_INCLUDE = /usr/include/python2.6

 ################################################################

@@ -26,7 +26,7 @@
 JPEG_OBJECTS = $(JPEG_SRC)/rdswitch.o \
           $(JPEG_SRC)/cdjpeg.o      \
           $(JPEG_SRC)/transupp.o \
-          $(JPEG_SRC)/libjpeg.a
+          /usr/lib/libjpeg.a

 PY_OBJECTS = transform.o py_jpegtran.o


$ cp -pr jpegtran /path/to/python/libpath

python-jpegtranはjpegtranのmain関数をmain_jpegtranって名前に変えて、 Pythonから使えるようにした感じになってました。

処理の比較

PIL / GraphicsMagick(gmコマンド) / pgmagick / ImageMagick(convertコマンド) / jpegtranコマンド / python-jpegtran で劣化するかどうかを試してみました。 90°回転を4回繰り返し元の角度に戻して、元画像と差分が発生するかで検証します。

検証スクリプト等は以下を参照していただきたいのですが、 "image diff calculate"以降の値が0より大きいと元のファイルから 差分が大きくなっています。

画像の比較方法は以下を参考にしました。

2枚の画像のdiff(差分)を超簡単に調べる方法 - 床のトルストイ、ゲイとするとのこと

結果としてはPIL/ImageMagickは1回目から劣化あり、GraphicsMagick/pgmagickが 2回目で劣化ありとなりました。

$ hg clone http://www.hexacosa.net/hgrepos/python-image-rotate/
$ cd python-image-rotate
$ make
[execute image rotating]
sh ./im.sh
sh ./gm.sh
sh ./jpegtran.sh
python ./pgm.py
python ./pil.py
python ./pyjpegtran.py
=======================
[image diff calculate]
sh imagediff.sh
pil             :829.285
jpegtran1       :0
jpegtran2       :0
pyjpegtran1     :0
pyjpegtran2     :0
im1             :242.282
im2             :308.635
gm1             :0
gm2             :0.107083
pgm1            :0
pgm2            :0.107083
=======================

http://www.hexacosa.net/hgrepos/python-image-rotate/file/tip

まとめ

JPEG画像を劣化無しで処理する場合は、python-jpegtranを使ったほうがよさそうです。 ただし、GraphicsMagick/pgmagickは2回目が劣化有りだったので、100回くらい 回転させるともっと差分が増えるかと思っていたのですが、100回回転させても 値が変わりませんでしたので、ほぼ劣化無しと考えて良いかもしれません。