Python3.3対応画像処理ライブラリ Pillow(PIL) の使い方

Pillowとは

Pillowは、Pythonの画像処理ライブラリで、Python Imaging Library (PIL)のforkプロジェクトです。

PILは開発が停滞しPython2.7までの対応にとどまっていますが、PillowはPython3.3に対応しています。

環境

pipでインストールできます。

Windowsの場合、error: Unable to find vcvarsall.bat というエラーが出て、これはVisual C++ のなにがしを導入すると解消するらしいのですが、僕の環境で2008やら2012やらを入れても解消できなかったので諦めてMacでやりました。

Windows7に入りました。pipではなくて easy_install を使ったらインストールできた。。何故だ。

libjpegやlibpngに依存するので入っていない場合は入れます。Mac OS X Portsで手に入る .dmg から入れるのが手っ取り早そう。Linux系ならyumなりなんなりで。この手順は割愛。

インストールすると pilconvert などのコマンドラインツールが併せて導入されます。

使い方

前述の通りPILのforkなので基本的な使い方で困ったことがあったら本家PILのドキュメントを参照するのが良い。ただし、メソッド自体の解説はあるが引数についての説明が割愛されている(?)ため見ただけではよくわからないので、詳細な動きはソースを読んだほうが良さそうです。

Pillowの利用の流れとしては次の通りです。

  1. 既存画像ならImage.openで開き、新規画像ならImage.newでcanvasを作成する。
  2. ImageDrawなどで画像オブジェクトを処理する。
  3. Image.saveで保存。

実際に使ったあたりで機能を列挙すると、

  • リサイズ
  • 回転
  • 色調操作
  • フォーマット変換
  • 合成(レイヤの重ね)
  • テキストの画像出力

などがあって、各々割とお手軽に行えます。他にも色々機能がありますが今回は基本的な使い方を書いていきます。

リサイズ

さっそくリサイズから。

saveについては見ての通り保存するだけですが詳細は後述。

テキストの画像出力

リサイズではImageだけ読み込みましたが今度はImageDrawとImageFontも読み込みます。

draw.textで指定するfillには16進数のカラーコードが使えます。この例だと、作成した縦40, 幅80の画像の座標(10, 10)を始点にしてテキスト「hogehoge」が書き込まれます。カラーは黒。

複数の画像を並べて1枚の画像にする

100 x 100 の画像 a.jpg と、100 x 100 の画像 b.jpg を、縦にマージして 200 x 100 の画像 c.jpg を作成したいとします。

既存画像の読み込みの他に、土台となる画像を一枚作成しておくのがミソ。あとはコメントの通り。(これが一番シンプルぽいのですが他にやり方あったら教えてくだしあ)

また、例ではべた書きしていますが、実際に利用する場合は、canvas = Image.new で指定するサイズはマージしたい画像から取得して合計した値を与える、、とかしておいたほうが便利と思います。

画像の品質について

ImageMagicのほうが加工後の画質が良いという意見も見かけましたが比較を見た/したわけではないので分かりません。が試行錯誤した結果画質をそんなに劣化させずに出来そうなポイントが2つほどありました。

.save では quality を明示する

例でも記載した .save でJPG画像を保存する際、quality にその名の通り品質を指定できる。これを明示しないとデフォルトの quality = 75 が適応されてしまう。100にしたらJPEGのクオンタイズが無効になるからアカンよ、みたいなことが書かれているがやってみると実害は特に感じられなかったので前述の例では100にしてみました。

未指定(=75)と100では一寸見れば違いが分かる、くらいには差がでました。

縦横比維持の縮小目的ならresizeよりもthumbnailのほうが良い(かも知れない)

150pxくらいの画像を100pxに縮小したらジャギが目立つようになってこれはアカンかも。。とげんなりしていたところ、サムネイル作成用の関数を利用しても縮小ができるようだったので試してみました。

リサイズ以外の処理も微妙に変わっているのは、resizeは戻り値としてリサイズ後の画像オブジェクトを返すのに対して、thumbnailは画像オブジェクト自体を書き換えるという違い(罠)があるため。もちろん保存時にファイル名を別にすれば既存画像が上書きされるなんてことはないですけれど。

で、実際にやった例だとこっちのほうが圧倒的に画質が良いことが分かりました。当社比で言うと120%程度(適当)。thumbnailの引数には、サイズとフィルタを指定できますが、フィルタに Image.ANTIALIAS を指定するとアンチエイリアスが効いて、あとは妖精さんが宜しくやってくれているようです。

optimize=Trueはやってもやらなくてもファイルサイズがちょっと増減するだけで見た目には影響しませんでした。元画像のサイズ、品質、加工後のサイズ、縮小するのか拡大するのか、等々によって最終的に得られる画像の品質は異なると思われ、指定するパラメータの最適値も変わってくると思います。

  • http://librabuch.jp/2013/05/python_pillow_pil/trackback/