Python Pillowを利用して画像処理を行ってみよう
複数の画像を一括でリサイズしたい場合にどうやって行っていますか?
リサイズを行いたい場合はPhotoshopやペイントといった画像編集ツールからブラウザ経由でリサイズするオンラインサイトまたはインストール型の無料ソフトウェアなど人によって利用するツールがさまざまだと思います。扱う画像が少なければPhotoshopなどのツールでもいいかもしれませんが数が増えると効率が急激に下がります。またオンラインサイトや無料ツールはセキュリティ的に問題がないのかという不安がいつも付きまといます。
そんな時にPythonを使っている人または使ってみたい人におすすめなのがPythonの画像処理ライブラリPillowを使ったリサイズです。
大量の画像も一括リサイズを簡単に行うことができるのでPythonを使って仕事の効率化を考えている人はぜひチャレンジしてみてください。
本文書の処理はWindows10環境を使って行っています。
目次
Pillowとは
PillowはPython Image Library(PIL:Python画像ライブラリ)から派生したライブラリで、画像のサイズ変更やトリミング、輝度やコントラストの変更など画像に関するさまざま処理を行うことができます。PILを元に作られているライブラリなので、Pillowモジュールを利用する場合はPILという名前を使用します。
Pillowのインストール
環境によってはインストール済みの場合もあるのでpip listコマンドで確認を行います。
>pip list
Package Version
---------- -------
・・・
Pillow 5.3.0
・・・
上記のように表示される場合はインストール済みなのでインストールは必要ありませんが、最新版でない場合はアップデートを行います。
インストールされていない場合は、pipコマンドを利用してPillowのインストールを行います。
>pip install Pillow
Collecting Pillow
Downloading Pillow-10.1.0-cp312-cp312-win_amd64.whl.metadata (9.6 kB)
Downloading Pillow-10.1.0-cp312-cp312-win_amd64.whl (2.6 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.6/2.6 MB 7.6 MB/s eta 0:00:00
Installing collected packages: Pillow
Successfully installed Pillow-10.1.0
Pillowライブライのアップデートを行い場合は下記のコマンドを実行します。
>pip install -U Pillow
インストールまたはアップデート後は、インストールが完了しているか確認するためにpip listコマンドを再度実行しましょう。
本環境では、バージョンである10.1.0であることがわかります。
>pip list
Package Version
---------- -------
・・・
Pillow 10.1.0
・・・
画像の処理
画像ファイルを開く
Pillowを使って画像ファイルを読み込んで、読み込んだ画像をWindowsのアプリで表示させます。
pythonプログラムを保存しているフォルダにpillow_github.pngというファイル名で画像を保存します。p画像ファイルが各自が準備してください。
アプリで画像を開くコードは下記の通りです。Imageのopenメソッドにはファイル名を指定してください。下記のコードでは画像とプログラムファイルが同じディレクトリに保存されています。
from PIL import Image
im = Image.open("pillow_github.png")
im.show()
PILモジュールからImageクラスを読み込んで、openメソッドで画像パスを指定して画像を開いています。Windowsではファイルを開いた後showメソッドを実行すると”フォト”アプリケーションが起動して、開いたファイルの画像が画面に表示されます。
画像ファイルの情報を取得する
Pillowで開いた画像ファイルの属性情報はImageインスタンスが持つ属性(filename, size)を使って確認することができます。
from PIL import Image
im = Image.open("pillow_github.png")
print(im.filename) #ファイル名
print(im.size) #サイズ
print(im.width) #幅
print(im.height) #高さ
print(im.mode) #モード
print(im.format) #フォーマット
実行すると各属性値を取得することができます。
pillow_github.png
(1128, 890)
1128
890
RGBA
PNG
画像をリサイズする
Pillowを利用することで画像の各種情報が取得できることがわかったのでPillowを利用してリサイズを行いたいと思います。サイズ1920, 1200の画像を320, 200に変更するプログラムです。わずか3行でリサイズを行うことができます。
変更を行いたいファイルはpythonプログラムが保存されているフォルダに保存しておく必要があります。サイズ変更後のファイルは同じフォルダに保存されます。画像のファイル名はimg8.jpgです。
from PIL import Image
im = Image.open("img8.jpg")
im_resized = im.resize((320,200))
im_resized.save('img8-1.jpg')
画像ファイルが存在しない場合には”FileNotFoundError: [Errno 2] No such file or directory: ‘img8.jpg’”エラーが表示されます。
横幅を指定して画像をリサイズする
リサイズしたい画像のサイズがいつも決まっている場合は、横、高さを固定した同じ設定でも問題ありません。通常は横、高さは画像によって異なる場合が大半です。そのような画像をリサイズする場合は、 縦横比を保ったままリサイズを行う 必要があります。
横幅を指定して縦横比を保ったままリサイズを行う方法を確認します。
from PIL import Image
im = Image.open("img8.jpg")
width = 700
ratio = width / im.width
height = int(im.height * ratio) #(5)
im_resized = im.resize((width, height))
im_resized.save('img8-1.jpg')
横幅に700を指定し、高さは縦横比を保つためにratioを求めます。そのratioを使って高さを出します。
元のサイズ1920, 1200 なので700, 437でリサイズされます。
リサイズした画像が粗い場合
リサイズを実行して画像が粗いと感じた場合はresizeメソッドを行う際のリサイズのフィルターを変更します。
フィルターは下記のものがあります。デフォルトは一番上のNEARESTの設定です。
- NEAREST
- BOX
- BILINEAR
- HAMMING
- BICUBIC
- LANCZOS
マニュアルには上記の設定に関する比較表は見つけられませんでしたが個別の説明はマニュアルの各所に記述されています。例えばHAMMINGはBILINEARと同じパフォーマンスである一方サイズの縮小の質はBICUBICと同じだがサイズを拡大する場合はあまり質が良くないと記述されています。どのフィルターが一番いいか検証も行っていなので、一番質が高いとされているLANCZOSを利用します。
変更方法は、resizeの際に下記のようにフィルターを設定します。
im_resized = im.resize((width, height), Image.LANCZOS)
実際にLANCZOSに変更して実行し、デフォルト設定のNEARESTに比較して画質が良くなっているか確認を行ってください。
複数の画像を一括処理
ここまでの説明でPillowを利用すると画像のリサイズが行えることがわかりました。ここからは画像のリサイズではなく複数の画像を一括で処理するための方法について説明を行っていきます。
複数の画像を扱う場合は、1つ1つの画像の名前をその都度入力していくことは非効率なのでできません。そのため、リサイズしたいファイルの名前を取得する機能が必要になります。
画像ファイルの名前を取得する
フォルダに保存されている画像ファイルの名前を自動で取得する方法が必要になります。
フォルダ下に保存されているファイル名を取得するためにglobモジュールを利用します。 拡張子がpngのファイルだけ取得しています。
import glob
for file_name in glob.glob('*.png'):
print(file_name)
実行するとpythonプログラムファイルが保存されているフォルダ内にある.pngファイルのみ取得することができます。
>py test.py
pillow_github.png
show_image.png
square.png
リサイズしたファイルを保存する場所
リサイズしたファイルを保存する場所を作成します。pythonプログラムファイルが保存されているフォルダの下にresizedフォルダを作成します。
リサイズされたファイルがすべてのそのフォルダに保存されるようにプログラムを更新します。
from PIL import Image
import os,glob
for file_name in glob.glob('*.png'):
im = Image.open(file_name)
width = 700
height = int(im.height * width / im.width)
im_resized = im.resize((width, height), Image.LANCZOS)
saved_path = os.path.join('resized',im.filename)
im_resized.save(saved_path)
globモジュールを使って取得したファイル一覧からforを使って個別のファイル名を取得します。
ファイルを横幅700のサイズでリサイズして、resizedフォルダに保存されるといったシンプルなものです。
実行後、resizedフォルダを見ると同じ名前で横幅が700になったファイルを確認することができます。