ユーニックス総合研究所

  • home
  • archives
  • python-pillow-resize

PythonのPillowで画像をリサイズする【拡大縮小】

  • 作成日: 2020-09-07
  • 更新日: 2023-12-24
  • カテゴリ: Python

PythonのPillowで画像をリサイズする

Pythonの外部ライブラリにPillowがあります。
これを使うと画像をリサイズして保存することが可能です。

画像を縮小するにはPillowresizeを使います。

from PIL import Image  

img = Image.open('img/sample.png')  
resized_img = img.resize((100, 100))  
resized_img.save('dst/out1.png')  

↓の画像が

↓のようにリサイズされました。

Image.resizeの構造

Image.resize(size, resample=3, box=None, reducing_gap=None)  
  • size ... リサイズ後のサイズ(タプルで(width, height))
  • resample ... リサンプリング方法

sizeにはリサイズしたいサイズをピクセルで渡します。横幅150pxで高さ100pxのサイズにリサイズしたい場合は↓のようにします。

img.resize((150, 100))  

resampleにはリサンプリング方法を指定する定数を渡します。

  • PIL.Image.NEAREST
  • PIL.Image.BOX
  • PIL.Image.BILINEAR
  • PIL.Image.HAMMING
  • PIL.Image.BICUBIC or PIL.Image.LANCZOS

デフォルトではBICUBICが使われます。

もっとも速いのはNEARESTで、次にBOX, BILINEAR, HAMMING, BICUBIC, LANCZOSと続きます。
縮小で品質が良いのはLANCZOSで次にBICUBIC, HAMMINGと続きます。
拡大で品質が良いのはLANCZOSで次にBICUBICです。

つまりLANCZOSが品質では最高なわけですが遅いということですね。

Image.resizeの戻り値

resizeの戻り値はPIL.Image.Imageです。

from PIL import Image  

img = Image.open('sample.png')  
resized_img = img.resize((100, 100))  

print(resized_img)  
print(type(resized_img))  
<PIL.Image.Image image mode=RGB size=100x100 at 0x265536387C8>  
<class 'PIL.Image.Image'>  

リサイズされた直後の戻り値の画像はメモリ上に展開されています。
ファイルとして保存したい場合はImage.saveを使います。

resized_img.save('resized.png')  

元画像のサイズとの相対でリサイズする

Image.width, Image.height属性にアクセスするとそれぞれ画像の横幅、高さを参照することができます。
この属性との相対で、たとえば元画像の半分に縮小したい場合などは↓のようにします。

from PIL import Image  

img = Image.open('img/sample.png')  
resized_img = img.resize((img.width // 2, img.height // 2))  
resized_img.save('dst/out2.png')  

↓の画像が

↓のようにリサイズされました。

複数の画像をまとめてリサイズする

複数の画像をまとめてリサイズしたいケースがあります。
そういう時はglobと組み合わせて使います。
たとえば特定ディレクトリ以下のpngファイルをすべてまとめてリサイズするには↓のようにします。

import glob  
from PIL import Image  

files = glob.glob('./*.png')  

for i, fname in enumerate(files):  
    img = Image.open(fname)  
    resized_img = img.resize((img.width // 2, img.height // 2))  
    resized_img.save(f'{i}.png')  

元のファイル名にキーワードを付加したい場合は↓のようにos.path.splitextを使います。

import os  
import glob  
from PIL import Image  

files = glob.glob('./*.png')  

for fname in files:  
    img = Image.open(fname)  
    resized_img = img.resize((img.width // 2, img.height // 2))  
    ftitle, fext = os.path.splitext(fname)  
    resized_img.save(f'{ftitle}_half{fext}')