ChatGPT・スライドショー作成

2025/04/29

概要

HTMLページにJavaScriptでスライドショーを設置する。 以前、ウェブページに画像スライドショーを設置する際、PHPプログラムを使用して実装した。 PHPを使用した理由は、サーバーサイドで動的に画像ファイル一覧を取得できるためであり、フォルダに格納された複数の画像をランダムまたは順番に表示することが容易だったためである。 しかし、PHPコードは通常、純粋なHTMLファイルには直接組み込むことができない。PHPコードを動作させるためにはファイルの拡張子を「.php」に変更し、サーバー側でPHPエンジンによる処理を通す必要がある。このため、既存のHTMLファイル(拡張子が.html)をPHPファイルに変更する作業が発生した。 さらに、もともと長大なHTMLコードの中にPHPコードを追加したことで、コード全体がさらに長くなり、可読性や保守性が低下した。ファイルサイズの増加や、コードの見通しの悪さが運用上の課題として残った。 今回の改善では、ファイル拡張子を変更せず、もともとのHTML形式のままスライドショーを実現するために、クライアントサイド技術であるJavaScriptを用いることにした。 ここでは便宜上、HTMLファイル内に直接JavaScriptコードを記述しているが、本来であればJavaScriptを外部ファイル(例: script.js)に分離して読み込む方が、可読性や再利用性、メンテナンス性の観点で望ましい。 JavaScriptを使用する際の課題として、標準のJavaScriptのみでは、Webサーバー上のフォルダに格納されたファイル一覧を直接取得することができない。これはブラウザ上のセキュリティ制限(Same-Origin Policyなど)や、ファイルシステムへのアクセス権限の制約によるものである。 したがって、スライドショーで使用する画像ファイル名のリストを、あらかじめJavaScript内に手動で配列として書き出しておく必要があった。 しかし、この方法では、画像を追加・削除するたびに手動でリストを更新しなければならない。画像の数が少ないうちは問題にならないが、今回の用途では画像が100枚以上に増加する可能性もあり、管理の手間とミスのリスクが高くなることが想定された。 この課題を解決するために、ChatGPTに相談した結果、次のアプローチを取ることにした。 すなわち、Pythonプログラムを用いて、サーバー上の指定フォルダ内に存在する画像ファイルの一覧を取得し、それをJSON形式のファイル(例: images.json)にまとめるバッチ処理を行う。 このJSONファイルは静的ファイルであるため、HTMLファイル側のJavaScriptから簡単に読み込み、配列データとして利用できる。 この仕組みにより、画像の追加・削除はサーバーフォルダ内の操作だけで済み、JSONファイルをPythonスクリプトで再生成するだけで最新状態を反映できるようになった。結果として、運用負荷を大幅に低減し、スライドショー機能の維持・更新が容易になった。

スライドショー設置の仕組み
┌───────────────┐
│  サーバー (Webホスティング)    │
│ ┌────────────┐ │
│ │ images/フォルダ            │ │ ← 画像ファイル群 (jpg, png, webp など)
│ └────────────┘ │
│ ┌────────────┐ │
│ │ generate_images_json.py │ │ ← Pythonスクリプト (画像リストをJSONに変換)
│ └────────────┘ │
│ ┌────────────┐ │
│ │ images.json             │ │ ← 出力された画像リスト (静的JSONファイル)
│ └────────────┘ │
└───────────────┘

          ↓

┌────────────────────┐
│ HTMLファイル                     │
│ ─────────────────── │
│ ・HTMLレイアウト                  │
│ ・内部または外部JavaScriptコード │
│     → images.jsonを読み込む       │
│     → ランダムに画像を選んで表示   │
└────────────────────┘

jsonファイルを作るプログラム

save_images_json.py


import os import json # 画像フォルダのパス(index.htmlからの相対パス) image_folder = 'images' # 許可する拡張子リスト allowed_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp'] # 画像ファイル名一覧を作る image_files = [] for filename in os.listdir(image_folder): if os.path.splitext(filename)[1].lower() in allowed_extensions: image_files.append(os.path.join(image_folder, filename).replace('\\', '/')) # Windows対策 # JSONファイルに保存 with open(os.path.join(image_folder, 'images.json'), 'w', encoding='utf-8') as f: json.dump(image_files, f, indent=2, ensure_ascii=False) print(f"✅ images.json を {image_folder} フォルダに保存しました。画像数: {len(image_files)}枚")


images.json - 出来上がったjsonファイル。画像名のリストが配列に格納されている。

}

[ "images/21.jpg", "images/22.jpg", "images/23.jpg", "images/24.jpg", "images/25.jpg", "images/41a.jpg", ................................... ]


index.html - スライドを表示するプログラム


<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Random Slideshow</title> <style> #slideshow { width: 800px; height: 450px; margin: 0 auto; overflow: hidden; position: relative; } #slideshow img { width: 100%; height: 100%; object-fit: contain; position: absolute; opacity: 0; transition: opacity 1s ease-in-out; } #slideshow img.fade-in { opacity: 1; } </style> </head> <body> <div id="slideshow"> <img src="" class="active" alt="slideshow image"> </div> <script> fetch('images/images.json') .then(response => response.json()) .then(images => { const slideshow = document.getElementById('slideshow'); const imgElement = slideshow.querySelector('img'); function changeImage() { const randomIndex = Math.floor(Math.random() * images.length); const newImage = images[randomIndex]; const newImg = document.createElement('img'); newImg.src = newImage; newImg.alt = "slideshow image"; newImg.classList.add('fade-in'); // 追加する前にopacity=0を確実に描かせるため newImg.style.opacity = '0'; slideshow.appendChild(newImg); // フェードイン処理 requestAnimationFrame(() => { requestAnimationFrame(() => { newImg.style.opacity = '1'; // fade-inクラスではなく直接style指定するパターン }); }); // 古い画像を削除(1秒後) setTimeout(() => { const oldImgs = slideshow.querySelectorAll('img'); if (oldImgs.length > 1) { oldImgs[0].remove(); } }, 1000); } // 最初に画像をセット if (images.length > 0) { imgElement.src = images[Math.floor(Math.random() * images.length)]; imgElement.classList.add('fade-in'); } setInterval(changeImage, 5000); }) .catch(error => { console.error('画像リスト読み込みエラー:', error); }); </script> </body> </html>


テスト操作

JavaScriptで非同期処理fetchを使っているのでローカルのテスト環境にはサーバー環境が必要。

Desktop上にフォルダーslideを作成しサブフォルダーimagesに画像を格納しておく。images.jsonがimagesに作成される。

Desktop -- slide |- index.html |- save_images_json.py |- images---21.jpg | 22.jpg | images.json(作成)


windowsのコマンドプロンプトの操作


Microsoft Windows [Version 10.0.26100.3775] (c) Microsoft Corporation. All rights reserved. C:\Users\abcd>cd Desktop C:\Users\abcd\Desktop>python -m http.server 8000 Serving HTTP on :: port 8000 (http://[::]:8000/) ...


ブラウザで実行 http://localhost:8000/slide/index.html

サーバー実行サンプル

サーバーにアップロードしたサンプルhtmlの実行。見栄えをよくするために少々追加してある。 slideshow_sample

感想

今回は、ChatGPTに技術的精査も含めてレビューしてもらった記事を概要に少々長くなったが記した。


戻る