【Python】Pillowでまとめて画像圧縮!圧縮率も自由自在!

Pillowでまとめて画像圧縮アイキャッチ画像
スポンサーリンク

あぶちゃです。

このブログでは、AI×Pythonの力で日常をもっと便利にするアイデアを発信しています。

悩んでいる人

画像を一括で圧縮して作業を効率化できる方法はある?

以上のような疑問にお答えしていきます。

この記事で学べること
  • PythonのPillowライブラリを使って、画像を圧縮する方法
  • 「jpg」,「png」,「WebP」の3つの画像フォーマットの画像を、希望の圧縮率で、一括で圧縮する方法

この記事では、PythonのPillowライブラリを使い、画像を簡単に圧縮する方法を紹介します。

また、圧縮したい画像の種類によって異なるフォーマットごとに希望の圧縮率を指定し、フォルダ内の画像ファイルを一括で圧縮するためのPythonコードを紹介し、初心者の方でも分かりやすいように解説しています。

Pythonコードは、そのままコピペするだけで使えるように作成しましたので、自身の環境ですぐに画像圧縮の作業を効率化できます。

この記事を読むことで、Python初心者の方でもPillowライブラリを使い、画像を簡単に圧縮できるようになりますので、ぜひ参考にしてください

目次

今回のPythonプログラムで実現したいこと

画像圧縮をPythonで実現したい理由

画像圧縮の必要性

最近の画像は高画質のものが多く画像ファイルサイズが大きいため、転送や保存に問題が生じることがあります。

画像圧縮が必要になる状況例

  • ブログやWebページの読み込み速度が遅くなる
  • メールの添付ファイルのサイズ上限でメールを送信できない
  • 画像ファイルの保存やバックアップに必要なストレージ容量が多大になる

上記は一例ですが、画像圧縮は様々な場面で必要になってきます。

Webサイトを使った画像圧縮

画像圧縮ができる方法として、Webサイトを使った方法があります。

例えば、COMPRESS JPGなどが有名で、画像をWebサイトにアップロードすると画像のファイルサイズを縮小することができます。

Webサイトを使った画像圧縮のデメリット

しかし、Webサイトを使った画像圧縮方法にはいくつかデメリットがあります。

主なデメリットとしては、

  1. 一つ一つの画像ごとに圧縮設定を変える必要があり、時間がかかる。
  2. 画像を外部サーバーにアップロードするため、機密情報や個人情報が漏洩する可能性がある。
あぶちゃ

以上のデメリットを解決するために、Pythonにより画像圧縮が自由自在にできるプログラムを作成していきましょう!

今回、圧縮する画像のフォーマットとその特徴

画像のフォーマットはたくさんありますが、広く使われている「jpg」,「png」比較的新しいフォーマットで活用が期待されている「WebP」の3つのフォーマットの画像を圧縮するためのプログラムを作成していきます。

JPEGとPNGの違いに関しては、こちらの「JPEGとPNGの違いは何?イラストはどっちがいいかも解説」の記事が参考になります。

JPEG(拡張子:.jpg)

  • 最も広く使われている画像フォーマット
  • 画像の情報を圧縮することでファイルサイズを小さくしている
  • 鮮明な写真の場合に最適で、画像を圧縮することで大幅にファイルサイズを削減できる
  • 非可逆圧縮形式で、データが圧縮されると一部の情報が失われ、元の画像には戻せない
  • 何度も圧縮をすると画質が劣化していってしまう

PNG(拡張子:.png)

  • ウェブページやドキュメントなどで広く使われている画像フォーマット
  • 背景を透過させることが可能
  • 基本は可逆性圧縮形式のため、何度保存しても画像が劣化しにくい
  • JPEGに比べて、圧縮率が低い(ファイルサイズを小さくできない)
  • 画像の色数が多いと、ファイルサイズが大きくなってしまう

WebP(拡張子:.webp)

  • Googleが開発した比較的新しい画像フォーマット
  • 圧縮率を調整することで、JPEGとPNGの双方の利点を兼ね備えることができる
  • 普及が進んでおらず、対応していないブラウザもある

今回のPythonプログラムで実現したいこと

今回のPythonプログラムで実現したいことをまとめると以下になります。

実現したいこと

「jpg」,「png」,「WebP」の3つの画像フォーマットの画像を、希望の圧縮率で、一括で圧縮できること。

今回のPythonプログラムに必要な機能

上記の「実現したいこと」を達成するために必要な機能を、以下と定義しました。

必要な機能

  1. 「jpg」,「png」,「WebP」の3つの画像フォーマットの画像を圧縮できる
  2. 圧縮率を各画像フォーマットごとに指定できる
  3. フォルダ内の画像ファイルを一括で圧縮できる

今回、使用するpython ライブラリ

「Google Colaboratory (Colab)」を使うと自身のパソコンに開発環境を構築しなくても、ブラウザ上でPythonコードを書いたり、実行したりすることができます。

あぶちゃ

自身のPythonの開発環境がない方は、Colabを使うことで簡単にPythonを使ってみることができます!

Pillow

「Pillow」とは、Pythonの画像処理ライブラリの一つであり、様々な画像の加工や変換、表示、保存などが可能です。

具体的には、以下のような機能を提供しています。

  • 画像の読み込みと書き出し
  • 画像の回転、リサイズ、トリミング、モード変換などの基本的な画像処理
  • 画像にフィルターをかけたり、合成する

画像処理においては、「Pillow」はPythonの標準ライブラリである「OpenCV」と比べても使いやすいと評価されています。

あぶちゃ

今回は、Pythonの標準ライブラリである「OpenCV」ではなく、「Pillow」を使って画像圧縮を行います!

Pillow公式サイト

スポンサーリンク

事前準備と使用環境

pythonライブラリのインストール

Pillowのインストール

以下のコマンドをコマンドラインに入力して、Pillowをインストールすることができます。

pip install Pillow

使用環境

今回、使用した作業環境は以下になります。

今回の作業環境

  • Mac Apple M1
  • MacOS Ventura 13.2.1
  • python 3.9.7
  • Pillow 8.4.0

画像を圧縮するpythonコードと使い方の解説

Pythonコード

「jpg」,「png」,「WebP」の3つの画像フォーマットの画像を、希望の圧縮率一括で圧縮できるPythonコードは、以下になります。

from PIL import Image
import os

#######ユーザー入力変数#######

# 圧縮したい画像が保存されているフォルダパスを指定
file_path = "こちらに圧縮したい画像が保存されているフォルダパスを指定してください"

# 圧縮後の画像を保存したいフォルダパスを指定
save_file_path = "こちらに圧縮後の画像を保存したいフォルダパスを指定してください"

# 保存したい画像フォーマットを指定
# jpg, png, webpのいずれかを指定する
# 圧縮したい画像がjpg画像の場合の保存フォーマット
save_format_jpg = "jpg"

# 圧縮したい画像がpng画像の場合の保存フォーマット
save_format_png = "png"

# 圧縮したい画像がwebp画像の場合の保存フォーマット
save_format_webp = "webp"

# 保存したい画像のファイル名の接尾語を指定
save_filename_suffix = "_comp"

# 「jpg」と「webp」画像の圧縮率の指定
# 「jpg」の場合は、0-95, 「webp」の場合は、0-100で指定
compression_rate_jpg = 50
compression_rate_webp = 50

# 「png」画像の色数の指定
# 1 - 256で指定
compression_color_num = 256

##########プロセス処理部分##########

# フォルダの区切り文字を取得(windowとmacで異なるため)
Delimiter_path = os.sep

# 圧縮したい画像のファイル名取得
filename_pic_list = os.listdir(file_path)

# for文により、フォルダ内のファイルの数だけ、下記のコードを実行
for filename_pic in filename_pic_list:

    # 元の画像ファイル名をファイル名と拡張子に分割する。
    file, ext = os.path.splitext(filename_pic)

    # 画像フォーマットによる場合わけ
    if ext == '.png':
        # 圧縮したい画像の読み込み。
        img = Image.open(file_path + Delimiter_path + filename_pic)
        # 画像の色数を削減
        img = img.convert("P", palette=Image.ADAPTIVE,
                          colors=compression_color_num)
        # 画像を指定した色数で保存(pngの場合)
        img.save((save_file_path + Delimiter_path + file +
                 save_filename_suffix + '.' + save_format_png), optimize=True)

    elif ext == '.jpg' or ext == '.webp':
        # 圧縮したい画像の読み込み。
        img = Image.open(file_path + Delimiter_path + filename_pic)

        # 保存する画像フォーマットを拡張子により、指定
        if ext == '.jpg':
            save_format = save_format_jpg
            compression_rate = compression_rate_jpg
        elif ext == '.webp':
            save_format = save_format_webp
            compression_rate = compression_rate_webp

        # 画像を指定した圧縮率で保存(jpgとwebpの場合)
        img.save((save_file_path + Delimiter_path + file + save_filename_suffix +
                 "." + save_format), optimize=True, quality=compression_rate)

Pythonコードの内容 (ユーザー入力変数)

まずは、ユーザー入力変数の部分のコードについて、解説していきます。

ユーザー入力変数の部分は、自身の環境や希望の圧縮率に応じて、適宜変更してください。

「圧縮したい画像のフォルダパス」と「圧縮後の画像を保存するフォルダパス」を指定

“file_path”に、圧縮したい画像が保存されているフォルダパスを指定し、“save_file_path”に圧縮後の画像を保存したいフォルダパスを指定してください。

# 圧縮したい画像が保存されているフォルダパスを指定
file_path = "こちらに圧縮したい画像が保存されているフォルダパスを指定してください"

# 圧縮後の画像を保存したいフォルダパスを指定
save_file_path = "こちらに圧縮後の画像を保存したいフォルダパスを指定してください"

圧縮後に保存したい画像のフォーマットを指定

今回、元の画像フォーマットごとに、保存する画像のフォーマットを指定できるようにしました。

元の画像フォーマットと同じフォーマットで保存したい場合は、こちらを変更する必要はありません。

しかし、圧縮したい元の画像と違うフォーマットで圧縮後の画像を保存したい場合は、これらの変数に元の画像とは異なる画像フォーマットを指定してください。

# 保存したい画像フォーマットを指定
# jpg, png, webpのいずれかを指定する
# 圧縮したい画像がjpg画像の場合の保存フォーマット
save_format_jpg = "jpg"

# 圧縮したい画像がpng画像の場合の保存フォーマット
save_format_png = "png"

# 圧縮したい画像がwebp画像の場合の保存フォーマット
save_format_webp = "webp"

圧縮後の画像のファイル名の接尾語を指定

一括で画像を圧縮する際に、画像ひとつひとつに、保存するファイル名を指定するのは大変です。

そこで、圧縮後の画像を保存するファイル名を、「元のファイル名」+「save_filename_suffixで指定した文字列」で作成することにします。

# 保存したい画像のファイル名の接尾語を指定
save_filename_suffix = "_comp"

例えば、元の画像のファイル名が「sample_pic.jpg」の場合は、「sample_pic_comp.jpg」という画像ファイルが作成されます。

画像の圧縮率を指定

以下の部分で、それぞれの画像の圧縮率を定義します。

# 「jpg」と「webp」画像の圧縮率の指定
# 「jpg」の場合は、0-95, 「webp」の場合は、0-100で指定
compression_rate_jpg = 50
compression_rate_webp = 50

# 「png」画像の色数の指定
# 1 - 256で指定
compression_color_num = 256
JPGの場合

「jpg」の場合は、0-95で圧縮率を指定します。

  • 0の場合 : 圧縮率は高いが、画像のクオリティは低い
  • 95の場合 : 圧縮率は低いが、画像のクオリティは高い

下記は、pillow公式サイトに記載されているjpgの圧縮率設定の説明です。

quality

The image quality, on a scale from 0 (worst) to 95 (best), or the string keep. The default is 75. Values above 95 should be avoided; 100 disables portions of the JPEG compression algorithm, and results in large files with hardly any gain in image quality. The value keep is only valid for JPEG files and will retain the original image quality level, subsampling, and qtables.

pillow公式サイト
WebPの場合

「webp」の場合は、0-100で圧縮率を指定します。

  • 0の場合 : 圧縮率は高いが、画像のクオリティは低い
  • 100の場合 : 圧縮率は低いが、画像のクオリティは高い

下記は、pillow公式サイトに記載されているwebpの圧縮率設定の説明です。

quality

Integer, 0-100, Defaults to 80. For lossy, 0 gives the smallest size and 100 the largest. For lossless, this parameter is the amount of effort put into the compression: 0 is the fastest, but gives larger files compared to the slowest, but best, 100.

pillow公式サイト
PNGの場合

「png」の場合は、他の画像フォーマットと異なり、圧縮率を変更して画像を圧縮することが困難です。

理由としては、可逆圧縮を使用しており圧縮の際にデータをあまり削減できないからです。

そこで、画像の色数を変更して、画像のファイルサイズを縮小します。

色数は、1-256で指定してください。

  • 1の場合 : 画像に使用する色の数が1色のみ
  • 256の場合 : 画像に使用する色の数が256色
参考情報【PNGの場合】

pngの場合も圧縮率を変更できる“compress_level”というオプションがあります。

しかし、pngのフォーマットの特性上、”compress_level”を変更してもあまり画像のファイルを縮小できないため、今回は使用していません。

下記は、pillow公式サイトに記載されている”compress_level”の説明です。

compress_level

ZLIB compression level, a number between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all. Default is 6. When optimize option is True compress_level has no effect (it is set to 9 regardless of a value passed).

pillow公式サイト
あぶちゃ

“compress_level”の影響を知りたい方は、以下のコードで試してみてください。

# 画像を指定した圧縮率で保存
img.save((save_file_path + '/' + file +
                 save_filename_suffix + "." + save_format_png), compress_level=6)

コードの53〜55行目を上記のコードに変更し、”compress_level”の数値を1-9の間で変更することで、圧縮率を変更することができます。

Pythonコードの内容 (プロセス処理部分)

次に、プロセス部分のコードを解説していきます。

コード内に説明を記載してますので、画像圧縮に関連する重要な部分のみ説明します。

画像の読み込み(Pillowライブラリ)

Image.open()メソッドを使用して画像の読み込みができます。引数には、圧縮したい画像のフォルダパスを指定します。

# 圧縮したい画像の読み込み。
img = Image.open(file_path + Delimiter_path + filename_pic)

画像の色数を削減(Pillowライブラリ)

img.convert()メソッドを使用して、画像のモードを変換できます。

ここでは、”P”というモードに変換しています。このモードは、パレットカラー(インデックスカラー)を使用して画像を表現するためのものです。

次に、palette引数には、Image.ADAPTIVEを指定しています。画像の色数を自動的に決定するための手法の1つで、colors引数で指定された数以下の色数で画像を表現します。

colors引数には、画像で使用する色数を指定します。

# 画像の色数を削減
img = img.convert("P", palette=Image.ADAPTIVE, colors=compression_color_num)

画像を指定した圧縮率で保存(Pillowライブラリ)

img.save()メソッドは、画像をファイルに保存するために使用されます。

引数にファイル名、ファイル形式、オプション(オプションには、圧縮率や最適化の有無などが含まれます)が指定されます。このメソッドを使用すると、Pythonで処理した画像を保存することができます。

メインコードの56〜58行目に記載されている「png」画像を保存するためのコード、72〜74行目に記載されている「jpg」,「webp」画像を保存するためのコードを以下にまとめて記載しています。

# 画像を指定した色数で保存(pngの場合)
img.save((save_file_path + Delimiter_path + file + save_filename_suffix + '.' + save_format_png), optimize=True)

# 画像を指定した圧縮率で保存(jpgとwebpの場合)
img.save((save_file_path + Delimiter_path + file + save_filename_suffix + "." + save_format), optimize=True, quality=compression_rate)

1行目の「png」画像用のコードは、png形式の画像を指定した色数で保存するために使用されます。具体的には、img.convert()を使用して、指定された色数のパレット画像に圧縮した後の画像を保存しています。

2つ目の「jpg」と「webp」画像用のコードは、画像を指定した圧縮率で保存するために使用されます。具体的には、optimize=Trueを指定し画像を最適化し、また、quality引数を使用して、指定された圧縮率で画像を保存しています。

実行結果

Pythonコードの実行結果

コードを実行した場合の結果は以下になります。

左が元の画像が保存されているフォルダのスクリーンショットで、右が圧縮後の画像が作成されたフォルダのスクリーンショットになります。

元の画像のファイルサイズと比較して、圧縮後の画像のファイルサイズが小さくなっていることがわかります。

圧縮前の画像が保存されているフォルダ
圧縮後の画像が作成されたフォルダ

“最後に” Pillowでまとめて画像圧縮!| まとめ

本記事では、PythonのPillowライブラリを使って、簡単に画像を圧縮する方法を解説しました。

本記事で紹介しているPythonコードにより、「JPEG」、「PNG」、「WebP」といった一般的に使用できる画像フォーマットで画像圧縮をおこなえます。

画像の圧縮率も自由自在で、簡単に一括圧縮できるので、大量の画像を効率的に処理することができます。

Pillowを使って簡単に画像を圧縮する方法を学んで、効率的な画像処理を実現しましょう!

最後まで、お付き合いいただきまして、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

あぶちゃのアバター あぶちゃ AI×Pyhonエンジニア

AI×Pythonの力で日常をもっと便利にするアイデアを紹介するブログ「AI Life Hacks」を運営中。
本業は、大手メーカーの機械系研究職であり、将来技術の研究やpythonによる機械学習などを用いたデータ分析に主に携わっている。

【実績】
20代で年収1000万を実現
5年間のドイツ駐在を通して、世界の最新技術に精通
訪れた国は30カ国以上

目次