import os
import glob
import csv
import tkinter as tk
from tkinter import filedialog, messagebox, simpledialog
from PIL import Image
def create_gallery_final():
root = tk.Tk()
root.withdraw()
# 1. フォルダの選択
messagebox.showinfo("選択", "1. 元画像が入っているフォルダを選択してください")
input_dir = filedialog.askdirectory(title="入力フォルダを選択")
if not input_dir: return
folder_name = os.path.basename(os.path.normpath(input_dir))
index_filename = f"{folder_name}.html"
csv_path = os.path.join(input_dir, "image_descriptions.csv")
messagebox.showinfo("選択", "2. 保存先(HTML・リサイズ画像)フォルダを選択してください")
output_dir = filedialog.askdirectory(title="出力先フォルダを選択")
if not output_dir: return
# --- 列数の指定 ---
num_cols = simpledialog.askinteger("列数設定", "一覧表の列数を入力してください(例: 3 や 4):", initialvalue=2, minvalue=1)
if not num_cols: num_cols = 2
# 上の階層へのリンク情報の入力
parent_page_name = simpledialog.askstring("戻り先設定", "上の階層のボタン名:", initialvalue="トップページへ戻る")
parent_page_url = simpledialog.askstring("戻り先設定", "上の階層のURL:", initialvalue="../index.html")
# 2. 画像ファイルの取得
valid_extensions = (".jpg", ".jpeg", ".png", ".bmp", ".webp")
images = []
for ext in valid_extensions:
images.extend(glob.glob(os.path.join(input_dir, f"*{ext}")))
images.extend(glob.glob(os.path.join(input_dir, f"*{ext.upper()}")))
images = sorted(list(set(images)))
if not images:
messagebox.showwarning("エラー", "画像が見つかりませんでした。")
return
# 3. CSVファイルの処理 (説明文の読み込み)
descriptions = {}
if not os.path.exists(csv_path):
with open(csv_path, 'w', encoding='utf-8-sig', newline='') as f:
writer = csv.writer(f)
writer.writerow(["ファイル名", "説明文"])
for img_path in images:
writer.writerow([os.path.basename(img_path), ""])
messagebox.showinfo("CSV作成", "説明入力用のCSVを作成しました。記入後、再実行で反映されます。")
else:
with open(csv_path, 'r', encoding='utf-8-sig') as f:
reader = csv.reader(f)
next(reader)
for row in reader:
if len(row) >= 2: descriptions[row[0]] = row[1]
# 4. 基本タイトルの入力とサイズ
base_title = simpledialog.askstring("タイトル", "ページ全体のタイトル:", initialvalue=folder_name)
target_width = simpledialog.askinteger("サイズ", "画像保存幅(px):", initialvalue=1200)
index_display_width = simpledialog.askinteger("サイズ", "一覧表示の最大幅(px):", initialvalue=400)
processed_data = []
# 5. 画像処理と個別HTML生成
for i, img_path in enumerate(images, 1):
fname = os.path.basename(img_path)
base_file_name = os.path.splitext(fname)[0]
desc_text = descriptions.get(fname, f"{base_title}-{i}")
try:
with Image.open(img_path) as img:
w, h = img.size
resized = img.resize((target_width, int(h * (target_width / w))), Image.Resampling.LANCZOS)
resized.save(os.path.join(output_dir, fname))
single_html = f"""<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{desc_text}</title>
<style>
body {{ text-align: center; font-family: sans-serif; background: #eee; padding: 40px; }}
img {{ width: 100%; max-width: 900px; border: 8px solid #fff; box-shadow: 0 0 10px rgba(0,0,0,0.1); }}
.desc {{ margin: 20px; font-size: 1.5em; font-weight: bold; }}
a {{ text-decoration: none; color: #007bff; font-weight: bold; border: 1px solid; padding: 10px 20px; border-radius: 5px; background: #fff; }}
</style>
</head>
<body>
<div class="desc">{desc_text}</div>
<img src="{fname}">
<div style="margin-top:30px;"><a href="{index_filename}">一覧に戻る</a></div>
</body>
</html>"""
with open(os.path.join(output_dir, f"{base_file_name}.html"), "w", encoding="utf-8") as f:
f.write(single_html)
processed_data.append((fname, base_file_name, desc_text))
except: pass
# 6. 一覧HTML生成 (列数に合わせて幅を自動計算)
col_width = 100 / num_cols
index_html = f"""<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{base_title}</title>
<style>
body {{ font-family: sans-serif; background: #f4f4f4; padding: 20px; }}
.header {{ text-align: center; margin-bottom: 30px; }}
.parent-nav {{ margin-bottom: 20px; }}
.parent-nav a {{ text-decoration: none; color: #666; border: 1px solid #ccc; padding: 5px 15px; background: #fff; }}
table {{ width: 100%; border-collapse: collapse; background: #fff; }}
td {{ border: 1px solid #eee; padding: 15px; text-align: center; vertical-align: top; width: {col_width}%; }}
img {{ width: 100%; max-width: {index_display_width}px; height: auto; }}
.caption {{ margin-top: 10px; font-size: 13px; font-weight: bold; }}
</style>
</head>
<body>
<div class="parent-nav"><a href="{parent_page_url}">← {parent_page_name}</a></div>
<div class="header"><h1>{base_title}</h1></div>
<table>"""
# 指定された列数 (num_cols) でループ
for i in range(0, len(processed_data), num_cols):
index_html += "<tr>"
for j in range(num_cols):
if i + j < len(processed_data):
f, b, d = processed_data[i+j]
index_html += f'<td><a href="{b}.html"><img src="{f}"><div class="caption">{d}</div></a></td>'
else:
index_html += "<td></td>"
index_html += "</tr>"
index_html += "</table></body></html>"
with open(os.path.join(output_dir, index_filename), "w", encoding="utf-8") as f:
f.write(index_html)
messagebox.showinfo("完了", f"{num_cols}列構成で作成しました。")
if __name__ == "__main__":
create_gallery_final()
|