画像ファイルをWebp形式に変換
[質問]
Pythonで、画像ファイルを読み込んで、拡張子が".webp"でなければWEBP形式に変換し、拡張子を".webp"に変えた名前で保存してください。Animated GIF や Animated PNG にも対応してください。CLIで「python image2webp.py ファイルパス1 ...」と、複数のファイルが指定できます。ファイル名はワイルドカードでも指定できます。
[回答] Grok
以下は、要求された仕様を満たすPythonスクリプトの例です。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
image2webp.py
使用方法:
python image2webp.py image1.jpg image2.png *.png anim.gif
python image2webp.py "写真フォルダ/*.jpg"
・ .webp で終わっているファイルはスキップ
・ それ以外の画像をWebPに変換
・ アニメーションGIF / APNG にも対応(透過・アニメーションを保持)
・ 元ファイルと同じ場所に「元ファイル名.webp」で保存
"""
import sys
import os
from pathlib import Path
from PIL import Image, ImageSequence
def convert_to_webp(filepath: str) -> bool:
"""
1つのファイルをWebPに変換
成功したらTrue、失敗したらFalseを返す
"""
path = Path(filepath)
# 既にwebpならスキップ
if path.suffix.lower() == '.webp':
print(f"スキップ(既にwebp): {path}")
return True
output_path = path.with_suffix('.webp')
try:
with Image.open(path) as im:
# アニメーションかどうかを判定
is_animated = getattr(im, "is_animated", False)
if is_animated:
# アニメーションGIF / APNG の場合
frames = []
durations = []
loop = 0
for frame in ImageSequence.Iterator(im):
frames.append(frame.convert("RGBA"))
# 各フレームの表示時間(ミリ秒)
durations.append(frame.info.get("duration", 100))
# APNGや一部GIFにあるループ回数
loop = im.info.get("loop", 0)
frames[0].save(
output_path,
format="WEBP",
save_all=True,
append_images=frames[1:],
duration=durations,
loop=loop,
quality=90, # 画質(0-100)
method=4, # 圧縮レベル(0=最速〜6=最高圧縮)
lossless=False
)
else:
# 通常の静止画
# RGBA → RGB に変換する場合もあるが、ここでは透過を保持
im = im.convert("RGBA")
im.save(
output_path,
format="WEBP",
quality=90,
method=4,
lossless=False
)
print(f"変換完了: {path} → {output_path}")
return True
except Exception as e:
print(f"エラー: {path} → {e}")
return False
def main():
if len(sys.argv) < 2:
print("使い方: python image2webp.py ファイルまたはワイルドカード...")
print("例: python image2webp.py *.jpg *.png anim.gif")
sys.exit(1)
success_count = 0
fail_count = 0
skip_count = 0
# コマンドライン引数を順に処理(シェルで展開されたパスが来る)
for arg in sys.argv[1:]:
path = Path(arg)
if path.is_file():
if convert_to_webp(path):
success_count += 1
else:
fail_count += 1
elif path.is_dir():
print(f"ディレクトリはスキップ: {path}")
else:
# ワイルドカードがシェルで展開されなかった場合(稀)
print(f"見つかりません: {arg}")
fail_count += 1
print("\n" + "="*50)
print(f"完了! 成功: {success_count} 失敗: {fail_count} スキップ: {skip_count}")
print("="*50)
if __name__ == "__main__":
main()```
### 使い方例
```bash
# 現在のフォルダ内のjpg,pngを全部変換
python image2webp.py *.jpg *.png
# 特定のファイルだけ
python image2webp.py photo.jpg meme.gif sticker.apng
# サブフォルダも含めたい場合はシェルで
find . -type f \( -iname "*.jpg" -o -iname "*.png" -o -iname "*.gif" \) -exec python image2webp.py {} +
主な特徴・対応状況
- 静止画(jpg, png, bmpなど)→ WebP(透過保持)
- アニメーションGIF → アニメーションWebP
- APNG(アニメーションPNG)→ アニメーションWebP
- 既存の
.webpファイルはスキップ - エラー処理あり(壊れた画像などはエラーメッセージ表示)
必要に応じて以下の値を調整してください:
quality=90→ 画質(80〜95くらいがバランス良い)method=4→ 圧縮努力度(6にするとさらに小さくなるが遅い)lossless=True→ ロスレス(ファイルサイズはかなり大きくなる)
楽しんで使ってください!
[修正版]
Windowsのコマンドプロンプトのワイルドカードにも対応しました
--> https://github.com/daisyroid/image2webp