Python(Pillow)を使って複数の画像ファイルをリサイズする処理

# 目次
[1.はじめに](#1-はじめに)
[2.使用環境](#2-使用環境)
[3.リサイズ](#3-リサイズ)
[4.ファイル取得](#4-ファイル取得)
[5.処理](#5-処理)
[6.ファイルを保存](#6-ファイルを保存)
[7.おわりに](#7-おわりに)

# 1. はじめに

画像を一括でリサイズ処理することがあったので、備忘録としてQiitaに載せておきます。
今回はPythonとその画像処理用ライブラリであるPillowを使用しました。

 **参考/使用したサイト一覧**

[Python, Pillowで画像を一括リサイズ（拡大・縮小）](https://note.nkmk.me/python-pillow-image-resize/)
[「それ、pythonでできるよ」－画像のリサイズ－](https://python-climbing.com/image_resize_python/)
[Pillow公式ドキュメント](https://pillow.readthedocs.io/en/stable/)
[指定した幅のサンプル画像を作成してくれるーplacehold.jp](https://placehold.jp/)


# 2. 使用環境

Python --3.9.1
Pillow --9.0.1

pythonとpillowのver対応は下記をご覧ください

 **Python - Pillowの対応表**
![Pillow対応表.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989672/5541bfb1-c028-c99c-130e-a77ab2e39768.png)

> Pillow公式ドキュメントより引用





# 3. リサイズ


PillowはPILをインポートして使用します。
```python
from PIL import Image
```


そして今回は画像のリサイズを行うためにresize()を使用します。

```　
resize((width,height),resample)
```
のように引数を指定して使用します。
width/heightの部分にはピクセル値を打ち込んで使うこともできるし、変数を使ったり元サイズの値を参照して指定することもできます。


 **ピクセル指定**
```python
image.resize((300, 240))
```



 **変数**
```python
img_width = 300
img_height = 240

image.resize((img_width, img_height))
```


 **リサイズ元画像を使用して指定（横幅を元画像の2倍、縦を1/2）**
```python
image.resize((img.width * 2, img.height // 2))
```


引数resampleでは、リサンプリングする際に使われるフィルターを指定できます。デフォルトではNEARESTが使われます。
フィルターの種類は
- NEAREST
- BOX
- BILINEAR
- HAMMING
- BICUBIC
- LANCZOS
です。

 **resampleフィルター指定**
```python
image.resize((hoge, hoge), resample=Image.NEAREST)
```


# 4. ファイル取得

今回はPATHを指定してファイルを取得していきます。
ここではglob()を使用して複数ファイルを一括取得していきます。
```python
import glob
import os

files = glob.glob('./hoge/*.png')
```
これでカレントディレクトリのhogeの中にあるpngファイルを全て指定できます。

拡張子を複数指定する場合の処理も後述します。

# 5. 処理

先ほどglob()で受け取ったファイルをresizeで処理していきます。まずpngファイルのみを処理します。

 **拡張子を指定して処理**

```python
import os
import glob
from PIL import Image

#PATH取得
files = glob.glob('./hoge/*.png')

#リサイズ処理
for f in files:
        img = Image.open(f)
        img_resize = img.resize((300, 240))
```

これでhogeディレクトリ内の.pngファイルが300x240にリサイズされます。処理したい拡張子がひとつのときはglob()のほうで指定するだけで可能です。

次に複数の拡張子を指定して処理します。

 **複数拡張子を指定して処理**
```python
#PATH取得、ここではすべてのファイルを対象とします。
files = glob.glob('./hoge/*')

for f in files:
    #指定した拡張子にだけ処理を加える
    root, ext = os.path.splitext(f)
    if ext in ['.jpg', '.png', '.jpeg']:
        #リサイズ処理
        img = Image.open(f)
        img_resize = img.resize((300, 240))
```

これでhogeディレクトリ内の.jpg, .png, .jpegファイルが300x240にリサイズされます。


# 6. ファイルを保存
処理が終わったら保存先を作成して保存しましょう。趣旨と少しはなれるので、ここはちゃちゃっといきます。

まずリサイズした画像の保存先のファイルを作成します。複数方法ありますが、ここではmakedirs()を使って作成します。

 **保存先ディレクトリの作成**
```python
dst_dir = './resized_images'
os.makedirs(dst_dir, exist_ok=True)
```
この書き方だと./hoge/hogehoge/resized_imagesのように指定して、途中に存在しないディレクトリを挟んだとしても/resized_imagesまでのディレクトリを作成してくれます。

では保存先のディレクトリに保存していきます。save()でファイルの保存ができます。

 **保存**
```python
img_resize.save('dst_dir')
```




 **さきほどの処理と合わせて記述すると**
```python
import os
import glob
from PIL import Image

#保存先の作成
dst_dir = './resized_images'
os.makedirs(dst_dir, exist_ok=True)

#PATH取得
files = glob.glob('./hoge/*')

#処理&保存
for f in files:
    root, ext = os.path.splitext(f)
    if ext in ['.jpg', '.png', '.jpeg']:
        img = Image.open(f)
        img_resize = img.resize((300, 240))
        img_resize.save('dst_dir')
```
これでhogeの指定した拡張子ファイルが300x240にリサイズされて/resized_imagesに保存されます。


# 7. おわりに

最後に自分が実際に書いた処理を載せておきます。
パスを取得して.jpg/.png/.jpegを指定したサイズの正方形にリサイズする処理です。
保存するときに"_resized(値)"をファイル名に追加しています。


```python
import os
import glob
from PIL import Image

#リサイズした画像の保存先ディレクトリ作成
dst_dir = './resized_images'
os.makedirs(dst_dir, exist_ok=True)

#PATH取得
files = glob.glob('./get_img/*')

 #resizeするpixel値指定して代入
img_size = 500

for f in files:
    root, ext = os.path.splitext(f)
    if ext in ['.jpg', '.png', '.jpeg']:

        #リサイズ処理
        img = Image.open(f)
        img_resize = img.resize((img_size, img_size))

        #リサイズした画像のファイル名に(_resized*値)を追加
        basename = os.path.basename(root)
        img_resize.save(os.path.join(dst_dir, basename + '_resized' + str(img_size) + ext))
```

正方形なので、リサイズしたい値が変更したときにimg_sizeに代入する値を変えれば一回で変わるようにしました。
ファイル名に追加する部分も変数の値が変われば変更されます。

また余談ですが、正方形のリサイズ時はwidthとheightの値がひとつでもいけるのか気になって試したところ
```
img.resize((img_size))
```
と記述するとエラーを吐きます。しっかり横x縦を書きましょう。

（追記）
```python
square_len = (img_size, img_size)
...
img.resize((square_len))
```
は可能です。（/追記）


ご覧いただきありがとうございました。
感想、アドバイスございましたらコメントでお願いいたします。