個人サイト制作:サイトマップへ戻る

個人サイト用の画像をまとめて操作するPython

フェードアウト効果の草花写真

Webサイト制作の効率を上げるPythonでは、主にExcelやPDFの処理に関するものを掲載しました。
むしろこちらの画像処理に関するもののほうが一般的かと思いますね。
特に大量の画像を扱う場合、そのファイル名リストを作ってまとめてhtml掲載するなど、普通に手作業でやると膨大な手間を要するシーンがあります。
また、大きな画像が多かった場合にレスポンスに悪影響を与えてしまい、それらのサイズ調整が必要になることもあるでしょう。
画像を1枚1枚、イラストソフトで開いて縮小していくなんて、気が遠くなってしまいます…

ここではそういった諸問題を解決できるPythonスクリプトを紹介していきます。

このpythonページの要約

このページに関する注意事項

当Webサイト作成者は、例示を目的としてマークアップ及びプログラミング例を提供しており、明示または黙示にかかわらず、いかなる責任も負わないものとします。
このページは、説明されているマークアップ及びプログラミング言語、手順を作成およびデバッグするために使用される各種ツールに読者が精通していることを前提にしています。
このページは、特定の機能を説明するのに役立つ可能性がありますが、当Webサイト作成者がこれらの例を変更した上で、特定の要件を満たすために追加の機能を提供したり、システムを構築したりすることはできません。
加えて、この例の手順に従う場合は、読者の各種ファイルを事前にバックアップすることを推奨いたします。

個人サイトに上げる画像には様々なサイズがある

大きな画像を大量に掲載すると、目に見えてWebページのレスポンスは落ちていきます。
とはいえ画像ファイルというのは往々にしてサイズがまちまちであり、大きな画像だけを調べてからサイズ調整するのは相当な労力となってしまいます。
Webサイトに上げようとしている画像はどんなサイズなのか、調べる必要が出てくるでしょう。
一括処理の対象範囲を絞らないと、十分に小さいサイズの画像まで縮めてしまったりするからです。

PIL(Python Imaging Library)のインストール

PIL(Python Imaging Library)はPythonに標準で含まれていないため、別途インストールが必要です。
ただ、現在はPILの後継であるPillowを使用するのが一般的です。
PillowはPILと互換性があり、より多くの機能とサポートを提供しています。
次のコマンドを実行すると、Pillowがインストールされ、スクリプト内で from PIL import Image として使用できるようになります。

Pillowをインストール


pip install Pillow
            

pythonで画像処理をさせようとすると、だいたいPILライブラリが必要になってくるんじゃないかな?
pythonをWeb制作に使う人なら、わりと早期に入れるライブラリだと思います。

複数画像の大きさをまとめて調査する

ここで紹介するのは画像の大きさをいっぺんに調査できるスクリプトです。
まずはこのスクリプトを実行して、Webページのレスポンスに大きな影響がありそうな巨大な画像があるかどうか、一括で調べるのです。
圧縮やサイズ変更を施す必要がある画像のリストを用意する段階ですね。

複数画像の大きさをまとめて調査するimage_size.py


import os  # OSモジュールをインポートして、ファイルやディレクトリの操作を行います
from PIL import Image  # PIL(Python Imaging Library)からImageクラスをインポートして、画像を操作します

# 指定されたディレクトリ内の画像ファイルのサイズを取得する関数
def get_image_sizes(directories):
    image_sizes = []  # 画像サイズを格納するリストを初期化します
    for directory in directories:  # 各ディレクトリについてループします
        for filename in os.listdir(directory):  # ディレクトリ内の各ファイルについてループします
            if filename.endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp')):  # 画像ファイルの拡張子をチェックします
                filepath = os.path.join(directory, filename)  # ファイルパスを作成します
                with Image.open(filepath) as img:  # 画像ファイルを開きます
                    width, height = img.size  # 画像の幅と高さを取得します
                    image_sizes.append(f"{filename} ({directory}): {width}x{height}")  # 画像サイズ情報をリストに追加します
    return image_sizes  # 画像サイズ情報のリストを返します

# 画像サイズ情報をテキストファイルに保存する関数
def save_sizes_to_file(image_sizes, output_file):
    with open(output_file, 'w') as file:  # 出力ファイルを開きます(書き込みモード)
        for size in image_sizes:  # 各画像サイズ情報についてループします
            file.write(size + '\n')  # 画像サイズ情報をファイルに書き込みます

# メインプログラム
if __name__ == "__main__":
    # 画像ファイルが含まれるディレクトリのパスを指定します
    directories = [r'C:\Users\image',
                    r'C:\Users\paint']
    # 出力ファイルのフルパスを指定します
    output_file = r'C:\Users\image_sizes.txt'
    # 画像サイズ情報を取得します
    image_sizes = get_image_sizes(directories)
    # 画像サイズ情報をファイルに保存します
    save_sizes_to_file(image_sizes, output_file)
    # 処理完了メッセージを表示します
    print(f"Image sizes have been saved to {output_file}")
                

このスクリプトは、指定されたフォルダ内の画像ファイルのサイズ(幅と高さ)を取得し、その情報をテキストファイルに保存しています。
上記にあるのはコメントアウトを入れたスクリプトですが、改めて説明しましょう。

フェードアウト効果の草花写真
必要なライブラリのインポート
os:ファイルやディレクトリの操作を行うための標準ライブラリ
PIL(Pillow):画像を開いたり、サイズを取得するためのライブラリ
関数の定義
get_image_sizes(directories):指定されたフォルダ(ディレクトリ)内の画像ファイルのサイズを取得し、リストにまとめる関数
save_sizes_to_file(image_sizes, output_file):画像サイズのリストをテキストファイルに保存する関数
メイン処理
directories:画像ファイルが保存されているフォルダのパスをリストで指定
output_file:画像サイズの情報を保存するテキストファイルのパスを指定
get_image_sizes(directories)を呼び出して、画像サイズのリストを取得
save_sizes_to_file(image_sizes, output_file)を呼び出して、取得した画像サイズのリストをテキストファイルに保存
最後に、処理が完了したことを知らせるメッセージを表示

このスクリプトを実行すると、指定したフォルダ内のすべての画像ファイルのサイズがテキストファイルに記録されます。
例えば、image_sizes.txtというファイルに「画像名(フォルダ名)幅x高さ」という形式で保存されます。
まずはこのようにして手持ちの画像を調査して、大きすぎる画像があるかどうかを調べるのです。
シンプルなリスト形式を定義して出力させれば、人の目でも一目瞭然でしょ?

画像のファイルサイズを調整する

スマホのカメラで撮影した景色とかね。
高解像度で、画像のファイルサイズが大きかったりします。
でも旅行に行った時の写真とか、このサイトであれば草花の写真は掲載したいもの。
ここでは画像のファイルサイズを2MB以下になるまで、一括して調整できるスクリプトを紹介します。

複数画像のファイルサイズをまとめて変更するpython

このスクリプトは、指定されたフォルダ内の画像ファイルをJPEG形式で保存し、さらにファイルサイズが2MB以下になるまで画質を調整するものです。
次世代の画像ファイル形式でも良いのですが、まだまだ古いデバイスも現役で活躍していることが予想されるので。
あと数年経ったらまとめて変換しちゃおうと思っていますが、今のところはjpeg形式で十分でしょう。

このスクリプトの流れは以下の通りですが、私の組み方が正解とは限らないです。

  1. 指定されたフォルダ内のすべてのファイルをチェック
  2. 画像ファイル(.png, .jpg, .jpeg)のみを対象とする
  3. 画像ファイルをJPEG形式で保存し、初期の画質を85に設定
  4. 画像ファイルのサイズが2MBを超えている場合、画質を10%ずつ下げて再保存
  5. すべての画像ファイルの処理が完了したら、メッセージを表示

複数画像のファイルサイズをまとめて変更するflower_resize.py


import os  # ファイルやディレクトリの操作を行うための標準ライブラリ
from PIL import Image  # 画像を開いたり、保存したりするためのライブラリ

# 画像ファイルが保存されているフォルダのパスを指定
directory = r'C:\Users\flower'

# 指定されたフォルダ内のすべてのファイルをループで処理
for filename in os.listdir(directory):
    # ファイルが画像ファイル(.png, .jpg, .jpeg)であるかをチェック
    if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
        img_path = os.path.join(directory, filename)  # 画像ファイルのフルパスを取得
        with Image.open(img_path) as img:  # 画像ファイルを開く
            new_img_path = os.path.join(directory, filename)  # 新しい画像ファイルのパスを設定
            quality = 85  # 初期の画質設定(0〜100の範囲で指定)
            img.save(new_img_path, 'JPEG', quality=quality)  # 画像をJPEG形式で保存

            # 画像ファイルのサイズが2MBを超えている場合、画質を下げて再保存
            while os.path.getsize(new_img_path) > 2 * 1024 * 1024:  # 2MB = 2 * 1024 * 1024バイト
                img = Image.open(new_img_path)  # 再度画像ファイルを開く
                quality = int(quality * 0.9)  # 画質を10%下げる
                img.save(new_img_path, 'JPEG', quality=quality)  # 画質を下げて再保存

print("画像の処理が完了しました。")  # 処理完了のメッセージを表示
            

このスクリプトはかなり汎用性が高いんですよね。
大量の画像ファイルを一括して同じファイル形式にできて、ついでに圧縮までやってくれます。
昔からそうですが、基本的に私はファイルサイズが2MB以下になるまで画質を調整してますね。
完璧にやっているわけでもありませんが、だいたいの画像をそのくらいのサイズにしておけば、Webサイトに著しい悪影響は出ません。

ライブラリのインポート
os:ファイルやディレクトリの操作を行うための標準ライブラリ
PIL(Pillow):画像を開いたり、保存したりするためのライブラリ
フォルダの指定
directory:画像ファイルが保存されているフォルダのパスを指定
画像ファイルの処理
指定されたフォルダ内のすべてのファイルをチェック
ファイルが画像ファイル(.png, .jpg, .jpeg)であるかを確認
画像ファイルを開き、JPEG形式で保存します。このとき、初期の画質を85に設定
ファイルサイズのチェックと調整
保存した画像ファイルのサイズが2MBを超えている場合、画質を10%ずつ下げて再保存
この処理を、ファイルサイズが2MB以下になるまで繰り返す
処理完了のメッセージ
すべての画像ファイルの処理が完了したら、「画像の処理が完了しました。」というメッセージを表示

画像ファイルのサイズを効率的に管理するのは重要ですよ。
言い換えると、この画像管理が大変な部分かと思います。
テキストデータにみたいに手軽に一括置換とかできるわけじゃないからね。

画像のサイズをまとめて変更する

フェードアウト効果の草花写真

Webサイトのレスポンスに悪影響が出ないよう、画像を調整する方法はいろいろあります。

ここで紹介するのはサイズを小さくするものです。
もともとモバイル端末で閲覧する人が多いのですから、少々画像が小さくても問題はありません。
どうしても大きい画像を用意したいのであれば、テキストベースのハイパーリンクを付けて別途表示することもできます。

画像の大きさをまとめて変えるpython

このスクリプトは scale=0.8 ですから、80%まで小さくします。
0.3なら30% 、0.5なら50% となりますね。
上述の画像サイズをまとめて取得するスクリプトを使って画像の大きさを知ることができたら、その大きさに従って小分けしても良いですね。
各フォルダに分けて保管しておけば、このような画像の大きさをまとめて変えるスクリプトも走らせやすいです。

複数画像をまとめて80%小さくするimage_aspect_compression_big80.py

ちなみにこんなに長いファイル名にするのはお勧めしないです😅
運用面で混乱しないことを最優先にしているから、こうなるってだけですよ。


# PIL (Python Imaging Library) の Image モジュールと os モジュールをインポート
from PIL import Image
import os

# 画像ファイルのパスをリストとして定義
image_paths = [
    r"C:\Users\red.png",
    r"C:\Users\blue.png",
    r"C:\Users\sky.jpg",
    r"C:\Users\sea.jpg",
]

# 画像をリサイズする関数を定義
def resize_image(image_path, scale=0.8):
    # 画像を開く
    with Image.open(image_path) as img:
        # 画像の元のサイズを取得
        width, height = img.size
        # 新しいサイズを計算
        new_size = (int(width * scale), int(height * scale))
        # 画像をリサイズ
        resized_img = img.resize(new_size, Image.LANCZOS)
        # リサイズした画像を保存
        resized_img.save(image_path)

# 各画像ファイルに対してリサイズ関数を実行
for image_path in image_paths:
    resize_image(image_path)

# すべての画像がリサイズされたことを表示
print("すべての画像がリサイズされました。")
            

先ほども書きましたが、scale=0.8 となっているので、画像の大きさは80%まで小さくなります。
一方、0.3と書けば30% 、0.5なら50% となりますね。
スクリプトを少し変えてから実行するだけで、複数の画像をいっぺんに指定のサイズへ変更できるのです。
例えば、次のスクリプトは50%まで画像を小さくするものですが、scale のところ以外は変わりません。

複数画像をまとめて50%小さくするimage_aspect_compression_middle50.py


from PIL import Image
import os

image_paths = [
    r"C:\Users\red.png",
    r"C:\Users\blue.png",
    r"C:\Users\sky.jpg",
    r"C:\Users\sea.jpg",
]

def resize_image(image_path, scale=0.5):
    with Image.open(image_path) as img:
        width, height = img.size
        new_size = (int(width * scale), int(height * scale))
        resized_img = img.resize(new_size, Image.LANCZOS)
        resized_img.save(image_path)

for image_path in image_paths:
    resize_image(image_path)

print("すべての画像がリサイズされました。")
                    

複数画像もスクリプトで処理できる部分がある

フェードアウト効果の草花写真

このセクションで書いてきた2つのスクリプトは、指定された画像ファイルをリサイズして保存するものです。
このスクリプトのケースでは、実行するとリスト内のすべての画像が50%のサイズにリサイズされます。
レスポンシブデザインが重要な現在のWeb制作において、このタイプのスクリプトは使用頻度も極めて高いです。
画像のリサイズなんかいちいち手作業でやっていると、誤って画像を消してしまったり、ケアレスミスの確率が上がっていきます。
退屈な単調作業は人を疲弊させます。
続けてスクリプトを示しながら各部分の説明を書いていきますね。

1.ライブラリのインポート

from PIL import Image
import os
                

PIL(Python Imaging Library)の Image モジュールと os モジュールをインポートしています。

2.画像ファイルのパスをリストとして定義

image_paths = [
    r"C:\Users\red.png",
    r"C:\Users\blue.png",
    r"C:\Users\sky.jpg",
    r"C:\Users\sea.jpg",
]
                

リサイズする画像ファイルのパスをリストにまとめています。

3.画像をリサイズする関数を定義

def resize_image(image_path, scale=0.5):
    with Image.open(image_path) as img:
        width, height = img.size
        new_size = (int(width * scale), int(height * scale))
        resized_img = img.resize(new_size, Image.LANCZOS)
        resized_img.save(image_path)
                        

resize_image 関数は、画像ファイルのパスとリサイズのスケールを受け取り、画像をリサイズして保存します。
Image.open(image_path) で画像を開きます。
img.size で元の画像の幅と高さを取得します。
new_size で新しいサイズを計算します(この場合、元のサイズの50%)。
img.resize(new_size, Image.LANCZOS) で画像をリサイズします。
resized_img.save(image_path) でリサイズした画像を元のパスに保存します。

4.各画像ファイルに対してリサイズ関数を実行

for image_path in image_paths:
    resize_image(image_path)
                    

リスト内の各画像ファイルに対して resize_image 関数を呼び出し、リサイズを実行します。

5.完了メッセージを表示

print("すべての画像がリサイズされました。")
                

すべての画像がリサイズされたことを示すメッセージを表示します。

画像リストからhtmlコードを作成するプログラム

画像を扱うスクリプトは他の目的にも転用可能な、汎用性の高いものが多いんですよね。
このスクリプトは次のような動作となっています。

  1. 画像ファイルの名称をリストにしたテキストデータを用意
  2. そのテキストデータから画像ファイル名と拡張子を読み込む
  3. 読み込んだ画像ファイル名と拡張子をhtmlのテンプレートに挿入する
  4. 作成されたhtmlコードを出力する
フェードアウト効果の草花写真

今回は画像ファイルとしていますが、ファイル名と拡張子をリストにしたテキストデータさえあれば良いのですから、他のファイル種別であっても応用が利きます。
画像を何枚も並べるhtmlを一瞬で作ることができますし、それはpdfでもmp4でも同じです。
繰り返し貼り付けられるようなhtmlコードについては、このようにスクリプトで処理できることが多いです。

複数の画像が並ぶWebページを作成するimage_add.py


# 'filelist.txt' というファイルを読み込み、UTF-8 エンコーディングで開く
with open('filelist.txt', 'r', encoding='utf-8') as file:
    # ファイルの各行を読み込み、改行を削除してリストに格納
    filenames = [line.strip() for line in file.readlines()]

# HTML テンプレートを定義
html_template = """
<div class="content">
    <img src="icon/{0}" alt="{1}" class="graphicmini right-image fade-in-out">
    <p></p>
</div>
"""

# HTML 出力を初期化
html_output = ""
# ファイル名リストをループして処理
for filename in filenames:
    # ファイル名と拡張子を分割
    name, _ = filename.rsplit('.', 1)
    # テンプレートにファイル名と名前を挿入して HTML 出力に追加
    html_output += html_template.format(filename, name)

# 'output.html' というファイルを UTF-8 エンコーディングで開き、書き込みモードにする
with open('output.html', 'w', encoding='utf-8') as output_file:
    # 生成した HTML コードを書き込む
    output_file.write(html_output)

# HTML コード生成完了のメッセージを表示
print("HTMLコードを生成しました。")
            

このスクリプトは、filelist.txt からファイル名を読み込み、それぞれのファイル名を使ってHTMLコードを生成し、output.html に書き込むものです。
このようにしてhtmlコードを作ってしまえば、実際にレイアウトを整えるのもラクです。
手作業でやってたら大変ですよ?
応用が利く汎用性の高いプログラムですので、ちょっとコードを貼りつつ詳しく説明します。

1.ファイルを読み込む

with open('filelist.txt', 'r', encoding='utf-8') as file:
filenames = [line.strip() for line in file.readlines()]
            

ここでは、filelist.txt というテキストファイルを開き、その中の各行を読み取ってリストに保存しています。
line.strip() は各行の前後の空白を取り除きます。

2.HTMLテンプレートを定義する

html_template = """
<div class="content">
<img src="icon/{0}" alt="{1}" class="graphicmini right-image fade-in-out">
<p></p>
</div>
"""
            

これは、画像とその説明を含むHTMLのテンプレートです。
{0} と {1} は後でファイル名と説明に置き換えられます。

3.HTMLコードを生成する

html_output = ""
for filename in filenames:
    name, _ = filename.rsplit('.', 1)
    html_output += html_template.format(filename, name)
            

ここでは、各ファイル名についてテンプレートを使ってHTMLコードを生成しています。
filename.rsplit('.', 1) はファイル名から拡張子を取り除き、name として保存します。

ちなみにここで「生成」という言葉を使っていますが、これはPythonが生成AIという話ではありませんからね?
丁寧に言うと、Pythonという生成AIを使ってHTMLを作らせていますという話ではありませんよということです。
Pythonという言語を使ってプログラミングを行い、そのスクリプトを実行することによってHTMLが記述されるという意味です。
すでにPythonが何かをご存じの方であれば問題ないけどね。
昨今のSNSを見る限り、このような但し書きは必要でしょう。

4.生成したHTMLコードを書き込む

with open('output.html', 'w', encoding='utf-8') as output_file:
output_file.write(html_output)
            

生成したHTMLコードを output.html というファイルに書き込みます。

5.メッセージを表示する

print("HTMLコードを生成しました。")
            

最後に、「HTMLコードを生成しました。」というメッセージを表示します。

このようにして、filelist.txt に書かれたファイル名を使って、画像タグを含むHTMLファイルが生成されます。
ちょっとスクリプトを変えれば、filelist.txt に書かれたファイル名を使って、PDFへのリンクを含むHTMLファイルを生成させることも可能です。


サイトマップ

アナザーエデン関連ページ・サイトマップ

アナザーエデンの強敵戦やストーリーコンテンツのリスト、お勧めバッジなどを掲載したコーナーです。
期間限定のない普通のRPGですので、初心者でも安心して続けていけるゲームとなっています。
もっとも重要なグラスタについては、場所別に網羅した表があります。

個人サイトのホスティングとコンテンツ作成

個人でウェブサイトを作るにはどうすればいいか。
HTML・CSS・JavaScriptの書き方はもちろん、無料かつ広告なしでホームページを作る方法を掲載したコーナーです。
Webデザインやレイアウトについても書いてあります。

魚釣りなどアウトドアのエリア

ゲームとパソコンだけじゃなく、アウトドアも趣味なんです。
このコーナーでは魚釣りの記録とか、魚料理のレシピ、はたまたサイクリングなどなど。
アウトドアに関連するコンテンツが詰め込まれています。