1. #Ver3
  2. from flask import Flask, request, render_template_string
  3. from openai import OpenAI
  4. from PIL import Image
  5. import numpy as np
  6. import io
  7. import base64
  8. import os
  9. from skimage import color # ★ 追加:Lab変換に使用
  10. # === OpenAIクライアント設定 ===
  11. client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY") or "あなたのOpenAI keyをここに入力")
  12. app = Flask(__name__)
  13. # === HTMLテンプレート ===
  14. HTML_PAGE = """
  15. <!doctype html>
  16. <html>
  17. <head>
  18.     <title>パーソナルカラー診断(肌の写真)</title>
  19. </head>
  20. <body>
  21.     <h1>パーソナルカラー診断</h1>
  22.     <p>あなたの『 肌のみ 』が映った写真を『 .png 』形式のファイルをアップロードしてください。<br>
  23.     ??注意??<br>
  24.     ・顔などの個人情報が載らないようにしてください<br>
  25.     ・光(自然光、白い電気)に当たった写真を使用することでより正確になります</p>
  26.     <form method="POST" enctype="multipart/form-data">
  27.         <input type="file" name="image" accept="image/*" required>
  28.         <input type="submit" value="診断する">
  29.     </form>
  30.     {% if result %}
  31.         <h2>診断結果</h2>
  32.         <p>{{ result|safe }}</p>
  33.     {% endif %}
  34. </body>
  35. </html>
  36. """
  37. @app.route("/", methods=["GET", "POST"])
  38. def index():
  39.     result = None
  40.     if request.method == "POST":
  41.         file = request.files["image"]
  42.         image_bytes = file.read()
  43.         # === 画像から平均色を抽出 ===
  44.         image = Image.open(io.BytesIO(image_bytes))
  45.         image = image.convert("RGB").resize((100, 100))
  46.         pixels = np.array(image).reshape(-1, 3) / 255.0 # 正規化(0〜1)
  47.         # === RGB → Lab変換 ===
  48.         lab_pixels = color.rgb2lab(pixels.reshape(100, 100, 3))
  49.         avg_lab = lab_pixels.reshape(-1, 3).mean(axis=0)
  50.         L, a, b = avg_lab
  51.         # === GPTへのプロンプト ===
  52.         prompt = f"""
  53. あなたはプロのパーソナルカラー診断士です。
  54. 次のLab値は L={L:.1f}, a={a:.1f}, b={b:.1f} です。
  55. 以下の条件にのみ従って、パーソナルカラーを診断してください。
  56. 絶対最初にパーソナルカラーを簡潔に書いてください。もし中途半端な結果であればどちらも記入してください。
  57. 条件:
  58. 1. 彩度C* = √(a? + b?)
  59. 2. イエベ/ブルベ判定は (b - a) による。
  60.    - b - a > 10 → イエベ
  61.    - b - a < 5 → ブルベ
  62. 3. 明るさ判定
  63.    - L > 70 → 明るめ
  64.    - L < 60 → 深め
  65. 4. 彩度判定
  66.    - C > 35 → ビビッド
  67.    - C < 25 → ソフト
  68. 5. これらを組み合わせて4シーズンを決定:
  69.    - Spring: b - a > 10, L > 70, C > 35 です。
  70.    - Summer: b - a < 5, L > 70, C < 30 です。
  71.    - Autumn: b - a > 10, L < 60, C < 30 です。
  72.    - Winter: b - a < 5, L < 60, C > 35 です。
  73. この条件に従って、あなたが推測するパーソナルカラータイプを出し、
  74. 理由と似合う色、避けたほうがよい色を説明してください。
  75. """
  76.         # === OpenAI API呼び出し ===
  77.         response = client.chat.completions.create(
  78.             model="gpt-4o-mini",
  79.             messages=[
  80.                 {"role": "user", "content": prompt}
  81.             ]
  82.         )
  83.         result = response.choices[0].message.content
  84.     return render_template_string(HTML_PAGE, result=result)
  85. if __name__ == "__main__":
  86.     app.run(debug=True)
  87.