python

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

2021年6月10日

最近ブログに使う画像をWebP(ウェッピー)にしていますが、オンラインサービスで一枚一枚やっているとかなりの手間です。

そこでPythonを使って画像のリサイズからWebP形式に変換までを一括でやってしまう方法を考えました。Pythonをインストールしてこの記事にあるコードをコピペすれば出来るようになります。

参考

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

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

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

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

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

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

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

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

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

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

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

Pythonによる画像変換

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

── images
└── original

originalというサブフォルダに元画像を入れ、images内のバッチファイルでpyファイルを実行する流れ。別に分けなくてもいいよ、って方はそれでもOKです。

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
#白背景にしたものを一旦output.pngとして保存
    cv2.imwrite("output.png", img_white)
    img = Image.open("output.png")
#幅1200と指定してますが任意です
    height = round((img.height*1200)/img.width)
    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
#白背景にしたものを一旦output.pngとして保存
    cv2.imwrite("output.png", img_white) 
    img = Image.open("output.png")
#幅1200と指定してますが任意です
    height = round((img.height*1200)/img.width)
    print(height)
#webpを作成
    img_webp=img.convert('RGB')
#条件分岐 画像幅1200以上の場合はリサイズして保存
    if img.width>1200:
        img_resize = img_webp.resize(size=(1200,height), resample=Image.NEAREST)
#webpファイルを保存
        img_resize.save(title + '_1200.webp')
#メッセージ表示 任意で削除可能
        print(title+" resized")
#画像幅1200以下の場合はリサイズせずに保存
    else:
#リサイズせずにそのまま保存
        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で画像をリサイズしてWebP形式に変換する方法 まとめ

Pythonを勉強すると、ひとつひとつ手作業でやっていたことを自動化して手間も時間も節約できます。もはやプログラミングの基礎は社会人必須スキルの1つ。ホリエモンも言っている通りさわりだけでも勉強しておくと、確実に業務に反映させることが出来ると思います。

このページでは生活に役立つトピックを扱っています。ぜひ一度トップページもご覧ください。
トップページ

最近の記事

  • この記事を書いた人

ともぞう

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

-python