画像の回転処理に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回回転させても 値が変わりませんでしたので、ほぼ劣化無しと考えて良いかもしれません。