【Python】画像をリサイズしてWebP形式に変換までをワンクリックで実行する方法

2021年6月10日

最近ブログに使う画像をWebP(ウェッピー)にしています。

今まではオンラインサービスBulk Reizeで画像を縮小したのち、別のオンラインサービスで WebPへ変換していましたが、一枚一枚やっているとかなりの手間です。

そこでPythonを使って画像のリサイズからWebP形式に変換までを一括でやってしまう方法を考えました。

参考

この記事を書くに当たっては下記記事が参考になりました。

「それ、pythonでできるよ」-画像のリサイズ-

Pythonによる画像変換の下準備

Pythonがインストールされている前提で話を進めます。

まずはコマンドプロンプトにて必要なパッケージをインストールします。

PillowはPythonで画像を扱うためのライブラリ。さらに透過画像の背景を白くするための OpenCVも併せてインストールしておきます(※)。

png形式の透過画像は背景を白くしておかないと背景が真っ黒になってしまいます。

以下のコードをコマンドプロンプトにて打ち込み実行します。

 コマンドプロンプト
pip install Pillow
pip install opencv-python

コマンドプロンプトの起動

Windowsの場合は[Windowsキー」+[R]でファイル名を指定して実行を起動しcmdと入力

Pythonによる画像変換

作業フォルダは以下の通り。

── images
└── original

originalというサブフォルダに元画像を入れ、images内のバッチファイルでpyファイルを実行する流れ。

Pythonのpyファイルもimagesフォルダに入れておきますが、別の場所に置く場合はバッチファイルのパスを変えてください。

コマンドは以下の通りです。ファイル名は「imgReize.py」としていますがお好みで。

 imgReize.py
import os
import glob
import shutil
from PIL import Image
import cv2
import numpy as np
files = glob.glob('./original/*')#全てのファイルのパスを取得
    for f in files: #取得したファイルに繰り返し処理
    title, ext = os.path.splitext(f)#パスからファイル名を取得
    img_white = cv2.imread(f, -1)
    try: #透過背景がある場合以下を実行
        index = np.where(img_white[:, :, 3] == 0)
        img_white[index] = [255, 255, 255, 255]
    except Exception: #透過背景がない場合何もしない
        pass
    cv2.imwrite("output.png", img_white) #白背景にしたものを一旦output.pngとして保存
    img = Image.open("output.png")
    height = round((img.height*1200)/img.width) #幅1200と指定してますが任意です
    img_webp=img.convert('RGB') #webpを作成
    img_resize = img_webp.resize(size=(1200,height), resample=Image.NEAREST)
    img_resize.save(title + '_1200.webp') #webpファイルを保存
 
#output.png削除
os.remove("output.png")

#変換したwebpファイルをimagesフォルダに移動
source=glob.glob('./original/*.webp')
for i in source:
shutil.move(str(i),'C:\MyPythonScripts\images/')

#originalに残っているファイルを削除
source=glob.glob('./original/*')
for i in source:
os.remove(i)
  • 「originalに残っているファイルを削除」はオプション(不要なら消す)
  • 画像の幅を1200に指定していますがここは任意
  • pathの「C:\MyPythonScripts\images/」は任意のものに変更

バッチファイルは以下の通り。拡張子が.batであればファイル名はなんでもOK。

 imgResize.bat
cd C:\MyPythonScripts\images
python imgResize.py

パスの「C:\MyPythonScripts\images」は任意の場所です。


あとはoriginalフォルダに変換元画像を入れてバッチファイルを実行すると、リサイズされたWebP画像がimagesフォルダ内に作成されます。

バッチファイルの実行方法はコマンドプロンプトにドラッグ&ドロップするのが正しい作法のようですが、バッチファイルをダブルクリックで大丈夫です

バッチファイルについては下記記事を参考に。

参考

透過画像の背景を白くするところでは以下のサイトを参考にしました。

[Python+OpenCV]画像の透過部分を白塗する - Qiita

応用 サイズが大きな画像だけResizeする方法

上記のコマンドでは幅が1200ピクセル以下の画像も無理やり引き延ばしてしまうため、小さな画像は画質が荒くなってしまいます。

そこで画像の幅が1200以下ならそのままのサイズで、幅1200以上なら1200へ縮小する条件を追加したものが以下のコードです。

 imgWeb.py
import os
import glob
import shutil
from PIL import Image
import cv2
import numpy as np
files = glob.glob('./original/*')#全てのファイルのパスを取得
for f in files: #取得したファイルに繰り返し処理
    title, ext = os.path.splitext(f)#パスからファイル名を取得
    img_white = cv2.imread(f, -1)
    try: #透過背景を白背景に
        index = np.where(img_white[:, :, 3] == 0)
        img_white[index] = [255, 255, 255, 255]
    except Exception:
        pass
    cv2.imwrite("output.png", img_white) #白背景にしたものを一旦output.pngとして保存
    img = Image.open("output.png")
    height = round((img.height*1200)/img.width) #幅1200と指定してますが任意です
    print(height)
    img_webp=img.convert('RGB') #webpを作成
    if img.width>1200: #条件分岐 画像幅1200以上の場合はリサイズして保存
        img_resize = img_webp.resize(size=(1200,height), resample=Image.NEAREST)
        img_resize.save(title + '_1200.webp') #webpファイルを保存
        print(title+" resized") #メッセージ表示 任意で削除可能
    else: #画像幅1200以下の場合はリサイズせずに保存
        img_webp.save(title + '.webp')  #リサイズせずにそのまま保存
        print(title+" saved not resized") #メッセージ表示 任意で削除可能
#output.png削除
    os.remove("output.png")
#変換したwebpファイルをimagesフォルダに移動
source=glob.glob('./original/*.webp')
for i in source:
    shutil.move(str(i),'C:\MyPythonScripts\images/') 
#originalに残っているファイルを削除
source=glob.glob('./original/*')
for i in source:
    os.remove(i)

これを実行するバッチファイルは以下になります。

 imgWebp.bat
cd C:\MyPythonScripts\images
python imgWebp.py

まとめ

図書館で借りた本で学んだだけですがpythonを使うとあらかたのことが自動で出来てしまいます。さわりだけでも勉強しておくとあとはネットを見ながら何とかなります。pythonの勉強はおすすめです。

  • この記事を書いた人

ともぞう

アラフォーのサラリーマンです。ほかに『Chrome通信』や『初心者による初心者の為のウイスキーの話など。』などを運用しています。