Python コードで画像に枠線をつける方法【Pillow】

記事やドキュメントに貼り付けるスクリーンショット画像に枠線（ボーダー）をつけるためのコードを作ってみました。
コピペでも動きますので、よろしければ使ってみてください。

# 環境
今回の開発環境は下記のとおりです。

- PC
  - OS：Windows 11
- Python
  - Version：3.8.10
  - ライブラリ：pillow, webcolors



# コードの紹介
画像に枠線をつけるために画像加工を行える **Pillow** というライブラリを用いています。
また、枠線の色の指定を **16進数カラーコード** で指定を行いたいので、 **webcolors** というライブラリも用いています。


## ライブラリのインストール
ライブラリのインストールはお使いの環境にあわせて行ってください。

### pip の場合
```shell
pip install pillow
pip install webcolors
```

### poetry の場合
```shell
poetry add pillow
poetry add webcolors
```

:::note info
Poetry について
Poetry の詳細は、下記の記事を参考にしてください。
https://qiita.com/IoriGunji/items/290db948c11fdc81046a
:::

## ソースコード
Python のソースコードは下記のとおりです。

```image_liner.py
import os
import re
import glob
from typing import Final, List
from PIL import Image
import webcolors

COLOR: Final[str] = '#000000'
BORDER_SIZE: Final[str] = 1
IMAGE_EXTS: Final[List[str]] = ['png', 'jpg', 'bmp']

def main():
    chdir = os.path.dirname(__file__)
    files = glob.glob(os.path.join(chdir, '*'))
    for file in files:
        for ext in IMAGE_EXTS:
            if re.search(f'\.{ext}$', file):
                image_edit(file, BORDER_SIZE, COLOR)

def image_edit(img_path: str, border: int, color: str):
    img = Image.open(img_path)
    dir, file = os.path.split(img_path)
    output = 'resized'
    os.makedirs(os.path.join(dir, output), exist_ok=True)
    new_img = add_border(img, border, color)
    new_img.save(os.path.join(dir, output, file), quality = 100)

def add_border(pil_img: Image, border: int, color: str):
    return campus_resize(pil_img, border, border, border, border, color)

def campus_resize(pil_img: Image, top: int, right: int, bottom: int, left: int, color: str):
    width, height = pil_img.size
    new_width = width + right + left
    new_height = height + top + bottom
    rgb = webcolors.hex_to_rgb(color)
    new_pil_img = Image.new(pil_img.mode, (new_width, new_height), rgb)
    new_pil_img.paste(pil_img, (left, top))
    return new_pil_img

if __name__ == "__main__":
    main()
```

## 使い方
このソースコードの使い方は下記のとおりです。

1. 必要なライブラリのインストールを行います。
1. 上記のソースコードをコピペして `image_liner.py` を作成します。
1. 加工したい画像を `image_liner.py` と同じフォルダに保存します。
1. `image_liner.py` を実行します。
1. 変換された画像が `./resized` フォルダに出力されます。

### サンプル
試しに Qiita のスクリーンショット画像を加工してみます。
元画像には枠線がついていないのですが、加工後の画像には枠線がついているのが確認できます。
※なお、Qiita の場合は **CSS** で自動的に薄灰色の枠線が付与されます。

|Before<br />![Sample_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/17cca749-0f81-3557-ed15-abd22a5404ce.png)|After<br />![Sample_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/6ad3a8ef-9de5-ca6d-86ef-89db950fc3d6.png)|
|--|--|


## 設定の変更方法
このソースコードの設定を変える方法について説明します。

### 枠線の色を変えたい場合
下記の定数の値を変更します。

```python
COLOR: Final[str] = '#000000'
```

例：枠線の色を **コーラル色** に変えたい場合

```python
COLOR: Final[str] = '#ff7f50'
```

### サンプル
|Before<br />![Sample_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/6ad3a8ef-9de5-ca6d-86ef-89db950fc3d6.png)|After<br />![Sample_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/7fe54946-2bb3-9e3f-b836-e32363148925.png)|
|--|--|


### 枠線の太さを変えたい場合
下記の定数の値を変更します。
値は `px` になります。

```python
BORDER_SIZE: Final[str] = 1
```

例：枠線の太さを **3px** に変えたい場合

```python
BORDER_SIZE: Final[str] = 3
```

### サンプル
|Before<br />![Sample_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/7fe54946-2bb3-9e3f-b836-e32363148925.png)|After<br />![Sample_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/0dd21ca2-e365-1576-9402-47d65590eb58.png)|
|--|--|


### 読み込む画像の種類を変えたい場合
下記の定数の値を変更します。

```python
IMAGE_EXTS: Final[List[str]] = ['png', 'jpg', 'bmp']
```

例：gif を追加したい場合

```python
IMAGE_EXTS: Final[List[str]] = ['png', 'jpg', 'bmp', 'gif']
```