Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import json | |
| import pandas as pd | |
| import random | |
| import os | |
| from groq import Groq | |
| from prompt_engine import PromptGenerator | |
| from utils import load_techniques, load_styles, parse_prompt_result | |
| # モデル特性に基づくカラーテーマ設定 | |
| model_themes = { | |
| "deepseek-r1-distill-llama-70b": {"primary": "#3366cc", "secondary": "#b3c6ff"}, | |
| "llama-3.3-70b-versatile": {"primary": "#4b367c", "secondary": "#d1c4e9"}, | |
| "meta-llama/llama-4-maverick-17b-128e-instruct": {"primary": "#00897b", "secondary": "#b2dfdb"}, | |
| "mistral-saba-24b": {"primary": "#0277bd", "secondary": "#b3e5fc"}, | |
| "qwen-qwq-32b": {"primary": "#6a1b9a", "secondary": "#e1bee7"}, | |
| "o4-mini-2025-04-16": {"primary": "#10a37f", "secondary": "#d2f4ea"} | |
| } | |
| # 選択されたモデル(初回読み込み時のデフォルト値) | |
| current_model = "qwen-qwq-32b" | |
| theme = model_themes.get(current_model, {"primary": "#6a1b9a", "secondary": "#e1bee7"}) | |
| # ページ設定 | |
| st.set_page_config( | |
| page_title="AI Art Prompt Generator", | |
| page_icon="🎨", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # カスタムCSSの適用 | |
| st.markdown(f""" | |
| <style> | |
| .stApp {{ | |
| background-color: {theme["secondary"]}20; /* 20%の透明度 */ | |
| }} | |
| .stButton>button {{ | |
| background-color: {theme["primary"]}; | |
| color: white; | |
| }} | |
| .stTabs [data-baseweb="tab-list"] {{ | |
| border-bottom-color: {theme["primary"]}40; | |
| }} | |
| .stTabs [aria-selected="true"] {{ | |
| color: {theme["primary"]} !important; | |
| border-bottom-color: {theme["primary"]} !important; | |
| }} | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Groq APIクライアント設定 | |
| def get_groq_client(): | |
| return Groq(api_key=st.secrets["GROQ_API_KEY"]) | |
| # OpenAI APIキーの設定 | |
| def setup_openai_api(): | |
| if "OPENAI_API_KEY" in st.secrets: | |
| os.environ["OPENAI_API_KEY"] = st.secrets["OPENAI_API_KEY"] | |
| return True | |
| return False | |
| # データロード | |
| def load_data(): | |
| techniques = load_techniques() | |
| styles = load_styles() | |
| return techniques, styles | |
| # 初期化 | |
| client = get_groq_client() | |
| openai_available = setup_openai_api() | |
| techniques, styles = load_data() | |
| prompt_generator = PromptGenerator() | |
| # タイトルとイントロ | |
| st.title("🎨 MidJourney/nijiJourneyプロンプトジェネレーター") | |
| st.markdown(""" | |
| このツールは、MidJourneyとnijiJourneyで使用する高度なプロンプトを簡単に生成します。 | |
| 基本的な説明から始めて、AIが最先端のテクニックを応用した洗練されたプロンプトに変換します。 | |
| """) | |
| # サイドバー | |
| with st.sidebar: | |
| st.header("⚙️ 基本設定") | |
| mode = st.radio( | |
| "モード選択", | |
| ["MidJourney", "nijiJourney"], | |
| help="生成するプロンプトの対象となるAIツールを選択します" | |
| ) | |
| complexity = st.select_slider( | |
| "複雑さレベル", | |
| options=["シンプル", "バランス", "詳細", "実験的"], | |
| value="バランス", | |
| help="生成されるプロンプトの複雑さを調整します" | |
| ) | |
| # モデル選択セクションを追加 | |
| st.markdown("---") | |
| st.header("🧠 AIモデル") | |
| # Claudeのsonnetをモデル選択に追加 | |
| model_options = [ | |
| "deepseek-r1-distill-llama-70b", | |
| "llama-3.3-70b-versatile", | |
| "meta-llama/llama-4-maverick-17b-128e-instruct", | |
| "mistral-saba-24b", | |
| "qwen-qwq-32b" | |
| ] | |
| # OpenAI APIキーが設定されている場合のみGPTモデルを選択肢に追加 | |
| if openai_available: | |
| model_options.append("o4-mini-2025-04-16") | |
| model = st.selectbox( | |
| "AIモデルを選択", | |
| model_options, | |
| index=4, # デフォルトは qwen-qwq-32b | |
| help="使用するAIモデルを選択します。各モデルによって生成結果の特性が異なります" | |
| ) | |
| # モデル選択時に変数を更新 | |
| if model != current_model: | |
| current_model = model | |
| theme = model_themes.get(current_model, {"primary": "#6a1b9a", "secondary": "#e1bee7"}) | |
| # テーマの更新(実際には再読み込みが必要) | |
| st.markdown(f""" | |
| <style> | |
| .stApp {{ | |
| background-color: {theme["secondary"]}20; | |
| }} | |
| .stButton>button {{ | |
| background-color: {theme["primary"]}; | |
| color: white; | |
| }} | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # モデル情報の表示 | |
| model_info = { | |
| "deepseek-r1-distill-llama-70b": "DeepSeekのLLaMA 70Bベースモデル。知識と推論能力に優れています。", | |
| "llama-3.3-70b-versatile": "Meta AIの最新LLaMA 3.3。バランスの取れた高性能モデルで、多くのタスクに適しています。", | |
| "meta-llama/llama-4-maverick-17b-128e-instruct": "LLaMA 4 Maverickの指示チューニング版。小型ながら高性能です。", | |
| "mistral-saba-24b": "Mistral AIのSaba 24Bモデル。創造性と一貫性のバランスに優れています。", | |
| "qwen-qwq-32b": "Qwen QWQモデル。創造的な表現力が高く、芸術的プロンプトに適しています。", | |
| "o4-mini-2025-04-16": "OpenAIの最新o4モデルのコンパクト版。高度なコンテキスト理解と創造的なプロンプト生成能力に優れています。" | |
| } | |
| st.caption(model_info.get(model, "")) | |
| st.markdown("---") | |
| st.header("🧙♂️ テクニック設定") | |
| auto_select = st.checkbox("テクニックを自動選択", value=True, | |
| help="オフにすると手動でテクニックを選択できます") | |
| if not auto_select: | |
| selected_techniques = st.multiselect( | |
| "使用するテクニック", | |
| options=list(techniques.keys()), | |
| default=[], | |
| help="プロンプトに適用する特定のテクニックを選択します" | |
| ) | |
| else: | |
| selected_techniques = [] | |
| # メインインプット | |
| st.header("🎯 あなたのイメージを教えてください") | |
| user_input = st.text_area( | |
| "描きたいイメージを自由に入力してください", | |
| height=100, | |
| help="日本語で自然に入力できます。AIが最適な英語のプロンプトに変換します。" | |
| ) | |
| # 詳細設定タブ | |
| tab1, tab2, tab3, tab4 = st.tabs(["基本設定", "高度なテクニック", "専門家向け設定", "実験的機能"]) | |
| with tab1: | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| aspect_ratio = st.selectbox( | |
| "アスペクト比", | |
| ["1:1 (正方形)", "16:9 (横長)", "9:16 (縦長)", "3:2 (標準)", "4:3", "2:3", "カスタム"], | |
| help="画像の縦横比を設定します" | |
| ) | |
| if aspect_ratio == "カスタム": | |
| custom_ratio = st.text_input("カスタム比率 (例: 5:4)") | |
| aspect_ratio = custom_ratio if custom_ratio else "1:1" | |
| quality = st.slider( | |
| "クオリティ (--q)", | |
| min_value=0.25, | |
| max_value=5.0, | |
| value=2.0, | |
| step=0.25, | |
| help="高いほど詳細な画像が生成されますが、処理時間が長くなります" | |
| ) | |
| with col2: | |
| style_category = st.selectbox( | |
| "スタイルカテゴリ", | |
| list(styles.keys()), | |
| help="生成画像の基本的なスタイル方向性を選択します" | |
| ) | |
| style_options = styles[style_category] | |
| style = st.selectbox( | |
| "スタイル", | |
| style_options, | |
| help="具体的なスタイルを選択します" | |
| ) | |
| stylize = st.slider( | |
| "スタイル強度 (--s)", | |
| min_value=0, | |
| max_value=1000, | |
| value=100, | |
| step=50, | |
| help="AIの創造性レベルを調整します。高いほど創造的な結果になります" | |
| ) | |
| with tab2: | |
| if auto_select: | |
| st.info("「テクニックを自動選択」がオンになっています。AIが最適なテクニックを選択します。") | |
| else: | |
| st.markdown("### 選択したテクニック") | |
| if selected_techniques: | |
| for tech in selected_techniques: | |
| st.markdown(f"**{tech}**: {techniques[tech]['description']}") | |
| else: | |
| st.warning("テクニックが選択されていません。サイドバーから選択してください。") | |
| st.markdown("### テクニック解説") | |
| tech_df = pd.DataFrame({ | |
| "テクニック": list(techniques.keys()), | |
| "説明": [t["description"] for t in techniques.values()], | |
| "効果": [t["effect"] for t in techniques.values()], | |
| }) | |
| st.dataframe(tech_df, use_container_width=True) | |
| with tab3: | |
| st.markdown("### 専門家向け設定") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| camera_angle = st.selectbox( | |
| "カメラアングル", | |
| ["自動選択", "eye level", "low angle", "high angle", "dutch angle", "aerial view", "worm's eye view"], | |
| help="""カメラの撮影角度を指定します。 | |
| - eye level(アイレベル): 人間の目線の高さから撮影したような視点。最も自然で中立的な印象を与え、被写体を等身大に表現します。 | |
| - low angle(ローアングル): 被写体を下から見上げる角度。被写体に力強さ、威厳、優位性を与え、より大きく、より印象的に見せます。 | |
| - high angle(ハイアングル): 被写体を上から見下ろす角度。被写体を小さく、弱く、または無力に感じさせ、また全体的な状況を俯瞰的に捉えることができます。 | |
| - dutch angle(ダッチアングル): カメラを傾けて撮影する手法。不安定さや緊張感、違和感を表現し、心理的な不均衡を示唆します。 | |
| - aerial view(空撮視点): 高い位置から真下を見下ろす視点。広大な風景や複雑なシーンの全体像を捉え、鳥の目線で世界を見せます。 | |
| - worm's eye view(ワームズアイビュー): 極端な低アングルで、まるで地面のミミズの視点から見上げるような角度。被写体の壮大さや圧倒的な存在感を強調します。""" | |
| ) | |
| lens_type = st.selectbox( | |
| "レンズタイプ", | |
| ["自動選択", "wide angle", "telephoto", "macro", "fisheye", "tilt-shift", "normal"], | |
| help="""カメラレンズの種類を指定します。 | |
| - wide angle(広角レンズ): 広い視野を捉えるレンズ。風景や建築物、狭い空間内の撮影に適しており、空間に開放感を与えますが、画像の端に歪みが生じることがあります。 | |
| - telephoto(望遠レンズ): 遠くの被写体を拡大して撮影するレンズ。遠景を引き寄せ、背景を圧縮する効果があり、ポートレートや野生動物の撮影に適しています。 | |
| - macro(マクロレンズ): 極めて近い距離から小さな被写体を等身大以上に拡大して撮影するレンズ。花や昆虫、微細なテクスチャーなど、肉眼では見えにくい詳細を捉えます。 | |
| - fisheye(魚眼レンズ): 極端な広角レンズで、180度以上の視野を球面状に歪ませて撮影します。独特の湾曲した視覚効果を生み出し、夢幻的または超現実的な印象を与えます。 | |
| - tilt-shift(ティルトシフトレンズ): レンズの角度や位置を調整できる特殊なレンズ。ミニチュア効果(実物を模型のように見せる)や、遠近法の調整、建築物の垂直線を修正する効果があります。 | |
| - normal(標準レンズ): 人間の視野に近い自然な画角を持つレンズ。歪みが少なく、最も現実に近い見え方を再現します。一般的に50mm前後の焦点距離を持ちます。""" | |
| ) | |
| with col2: | |
| lighting = st.selectbox( | |
| "照明設定", | |
| ["自動選択", "natural light", "golden hour", "blue hour", "dramatic lighting", "backlight", "studio lighting"], | |
| help="""画像の照明条件を指定します。 | |
| - natural light(自然光): 人工的な照明を使わず、太陽や月などの自然の光源のみを利用した照明。自然で柔らかい質感を持ち、風景や日常シーンに現実感を与えます。 | |
| - golden hour(ゴールデンアワー): 日の出直後や日没直前の、太陽が地平線近くにある時間帯の温かく黄金色に輝く光。被写体に柔らかく暖かな光と長い影を与え、ロマンチックで魅惑的な雰囲気を作り出します。 | |
| - blue hour(ブルーアワー): 日の出前や日没後の、空が深い青色に染まる短い時間帯の光。神秘的で落ち着いた雰囲気を持ち、都市風景や夕暮れのシーンに幻想的な印象を与えます。 | |
| - dramatic lighting(ドラマチックライティング): 強いコントラストと方向性のある光と影を使った照明。緊張感や劇的な雰囲気を生み出し、被写体の立体感や質感を強調します。 | |
| - backlight(バックライト): 被写体の後ろから当てる光。シルエットや輪郭を強調し、被写体の周りに光の縁取り(リムライト)を作ります。神秘的で幻想的な雰囲気や、逆光による独特の効果を生み出します。 | |
| - studio lighting(スタジオライティング): 制御された環境での複数の人工光源を使った照明技術。精密なハイライトとシャドウのコントロールが可能で、商業写真やポートレートに用いられます。""" | |
| ) | |
| composition = st.selectbox( | |
| "構図", | |
| ["自動選択", "rule of thirds", "golden ratio", "symmetrical", "asymmetrical", "leading lines", "frame within frame"], | |
| help="""画像の構図テクニックを指定します。 | |
| - rule of thirds(三分割法): 画面を縦横それぞれ3等分するグリッド線上とその交点に重要な要素を配置する構図。バランスが良く、視覚的に心地よい安定した構図を作り出します。 | |
| - golden ratio(黄金比): 約1:1.618の比率を基にした構図。自然界に多く見られるこの比率は、人間の目に特に美しく調和の取れた印象を与えます。螺旋状のガイドラインに沿って主要素を配置することが多いです。 | |
| - symmetrical(シンメトリー): 左右または上下対称の構図。秩序、安定感、フォーマル感を与え、建築物や自然の反射など、対称性のある被写体に特に効果的です。 | |
| - asymmetrical(非対称): 意図的にバランスを崩した構図。動的な緊張感や興味を引き、よりカジュアルで自然な印象を与えます。視覚的な「重さ」を調整して全体のバランスを取ります。 | |
| - leading lines(リーディングライン): 道路、鉄道、川などの線状の要素を使って視線を画像内の特定の場所(通常は主題)へと導く構図。写真に奥行きと方向性を与え、視聴者の目の動きをコントロールします。 | |
| - frame within frame(フレームインフレーム): 窓、アーチ、木の枝などの要素を使って、画像内に別のフレームを作り出す構図。主題を強調し、奥行きを加え、視聴者の視線を中心に導きます。""" | |
| ) | |
| # MidJourney特有のパラメータセクションを追加 | |
| st.markdown("### MidJourney/nijiJourney特有のパラメータ") | |
| # タブでパラメータをカテゴリ分け | |
| param_tab1, param_tab2, param_tab3 = st.tabs(["スタイル参照", "パーソナライズ", "その他"]) | |
| with param_tab1: | |
| # スタイルリファレンス (--sref) 設定 | |
| use_style_reference = st.checkbox("スタイルリファレンス (--sref) を使用", | |
| help="""別画像のスタイルを参照し、色調や質感を新規生成に適用します。 | |
| 特定の画像のスタイル特性(色調、テクスチャ、画風など)を参照して新しい画像に適用するパラメータです。 | |
| 特定の画像URL、ランダム選択、または以前に生成した画像のコードを指定できます。""") | |
| if use_style_reference: | |
| sref_type = st.radio("参照方法", ["ランダム", "画像URL", "コード指定"], horizontal=True) | |
| if sref_type == "ランダム": | |
| st.info("ランダムに選ばれたスタイルが適用されます (--sref random)") | |
| sref_value = "random" | |
| elif sref_type == "画像URL": | |
| sref_value = st.text_input("画像URL", help="スタイル参照する画像のURLを入力してください") | |
| else: | |
| sref_value = st.text_input("スタイルコード", help="以前生成されたsrefコードを入力 (例: 1234567)") | |
| # スタイルウェイト | |
| style_weight = st.slider("スタイルウェイト (--sw)", 0, 1000, 100, | |
| help="""参照画像の影響度を調整します。高いほど強く反映されます。 | |
| 参照画像のスタイルがどの程度強く新しい画像に影響するかを0〜1000の値で指定します。 | |
| 値が高いほど参照スタイルの影響が強くなります。""") | |
| # スタイルバージョン | |
| style_version = st.radio("スタイルバージョン (--sv)", [1, 2, 3, 4], index=3, horizontal=True, | |
| help="""Style Referenceアルゴリズムのバージョンを選択します。 | |
| スタイル参照アルゴリズムのバージョン(1〜4)を選択します。 | |
| 新しいバージョンほど改良されていますが、それぞれ異なる特性を持っています。""") | |
| with param_tab2: | |
| # パーソナライゼーション (--p) 設定 | |
| use_personalization = st.checkbox("パーソナライゼーション (--p) を使用", | |
| help="""自身の好みに学習させたプロファイルを適用します。 | |
| ユーザーの好みに基づいて学習されたカスタムプロファイルを適用するパラメータです。 | |
| デフォルトプロファイル、特定のプロファイルID、または以前生成したコードを指定できます。""") | |
| if use_personalization: | |
| personalization_type = st.radio("適用方法", ["デフォルト", "プロファイルID", "コード指定"], horizontal=True) | |
| if personalization_type == "デフォルト": | |
| st.info("設定済みのデフォルトプロファイルが適用されます (--p)") | |
| personalization_value = "" | |
| elif personalization_type == "プロファイルID": | |
| personalization_value = st.text_input("プロファイルID", help="使用するプロファイルIDを入力") | |
| else: | |
| personalization_value = st.text_input("パーソナライズコード", help="以前生成されたコードを入力") | |
| # パーソナライズ強度は --stylize を共用 | |
| st.caption("パーソナライズの適用度はスタイル強度 (--s) パラメータで調整されます") | |
| with param_tab3: | |
| # その他のパラメータ | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| use_character_reference = st.checkbox("キャラクター参照 (--cref)", | |
| help="""複数シーンで同一キャラクターを維持します。 | |
| 特定のキャラクターの外見を維持しながら複数の画像を生成するためのパラメータです。 | |
| キャラクターが写っている参照画像のURLを指定します。""") | |
| if use_character_reference: | |
| cref_value = st.text_input("キャラクター参照URL", help="キャラクターが写っている画像のURLを入力") | |
| use_repeat = st.checkbox("繰り返し生成 (--repeat / --r)", | |
| help="""同一プロンプトで複数グリッドを生成します。 | |
| 同じプロンプトで複数セットの画像を連続して生成するパラメータです。 | |
| 時間を節約し、より多くのバリエーションを効率的に探索できます。""") | |
| if use_repeat: | |
| repeat_count = st.number_input("繰り返し回数", min_value=1, max_value=10, value=2) | |
| # ネガティブプロンプト追加 | |
| use_negative_prompt = st.checkbox("ネガティブプロンプト (--no)", | |
| help="""画像から除外したい要素を指定します。 | |
| 生成画像に含めたくない要素を指定するパラメータです。 | |
| 「bad hands」「text」「watermark」などの不要な要素を除外できます。""") | |
| if use_negative_prompt: | |
| negative_prompt = st.text_area("除外要素(コンマ区切り)", | |
| placeholder="例: text, watermark, bad hands, blurry", | |
| help="生成画像に含めたくない要素をコンマ区切りで入力") | |
| # タイル機能追加 | |
| use_tile = st.checkbox("タイル生成 (--tile)", | |
| help="""シームレスに繰り返し可能なタイル模様を生成します。 | |
| シームレスに繰り返し使用できるパターンやテクスチャを生成するためのパラメータです。 | |
| ウェブサイトの背景、壁紙、テキスタイル等に適しています。""") | |
| with col2: | |
| use_image_weight = st.checkbox("画像プロンプトの影響度 (--iw)", | |
| help="""画像プロンプト(イメージURL)の影響度を調整します。 | |
| 画像プロンプト(URLで提供される参照画像)が最終結果にどれだけ影響するかを0.0〜2.0の値で指定します。 | |
| 高い値ほど画像プロンプトの影響が強くなります。""") | |
| if use_image_weight: | |
| image_weight = st.slider("画像ウェイト", 0.0, 2.0, 1.0, 0.1) | |
| generation_mode = st.radio("生成モード", | |
| ["デフォルト", "fast", "relax", "turbo", "draft"], | |
| index=0, horizontal=True, | |
| help="""GPU速度やコストを最適化するモードを選択します: | |
| - fast(高速モード): より速く結果を生成するモード。品質はやや劣りますが、アイデアの迅速な検証に適しています。 | |
| - relax(リラックスモード): 通常より低い優先度で処理される低コストのモード。急ぎでない場合や、サーバー負荷が高い時間帯に適しています。 | |
| - turbo(ターボモード): 最も高速なモードで、数秒で結果を生成します。品質は最も低くなりますが、概念実証や迅速なアイデア検証に最適です。 | |
| - draft(ドラフトモード): より低解像度で高速に生成するモード。迅速なイテレーションに適していますが、最終的な高品質画像には向いていません。""") | |
| visibility = st.radio("共有設定", | |
| ["デフォルト", "public", "stealth"], | |
| index=0, horizontal=True, | |
| help="""MidJourneyサイトへの公開/非公開を制御: | |
| - public(公開): 生成した画像をMidJourneyのコミュニティギャラリーに公開します。他のユーザーが閲覧でき、コミュニティの参考になります。 | |
| - stealth(非公開): 生成した画像を非公開にします。他のユーザーには表示されず、完全にプライベートに保たれます。""") | |
| # seed値追加 | |
| use_seed = st.checkbox("シード値を指定 (--seed)", | |
| help="""同じ結果を再現するための値を設定します。 | |
| 生成プロセスを制御する数値シードを指定するパラメータです。 | |
| 同じシード値を使用すると同じ条件で同様の結果を再現できます。""") | |
| if use_seed: | |
| seed_value = st.number_input("シード値", | |
| min_value=0, | |
| max_value=4294967295, | |
| value=random.randint(0, 4294967295), | |
| help="特定のシード値を使用して再現性を確保します") | |
| random_seed = st.button("ランダムなシード値を生成") | |
| if random_seed: | |
| seed_value = random.randint(0, 4294967295) | |
| st.write(f"生成されたシード値: {seed_value}") | |
| # chaosレベル追加 | |
| use_chaos = st.checkbox("ランダム性設定 (--c/--chaos)", | |
| help="""結果の予測不能さを調整します。 | |
| 生成結果の多様性やランダム性を0〜100の値で調整するパラメータです。 | |
| 高い値ほど予測不能で創造的な結果が得られますが、プロンプトからの逸脱も大きくなります。""") | |
| if use_chaos: | |
| chaos_value = st.slider("Chaosレベル", 0, 100, 0, | |
| help="高いほど予測不能な結果になります") | |
| # stop値追加 | |
| use_stop = st.checkbox("途中停止 (--stop)", | |
| help="""生成過程を途中で停止させてラフな結果を得ます。 | |
| 生成プロセスを途中で意図的に停止させて中間結果を取得するパラメータです。 | |
| より未完成で実験的、アーティスティックな表現に適しています。""") | |
| if use_stop: | |
| stop_value = st.slider("停止ポイント", 10, 100, 100, | |
| help="生成プロセスをどの段階で停止するか (%)") | |
| # カスタムパラメータセクション | |
| st.markdown("### カスタムパラメータ") | |
| advanced_params = st.text_area( | |
| "カスタムパラメータ (JSONフォーマット)", | |
| "{}", | |
| help="上級者向け: 追加のカスタムパラメータをJSON形式で指定できます" | |
| ) | |
| with tab4: | |
| st.markdown("### 実験的機能") | |
| st.warning("これらの機能は予測不能な結果をもたらす可能性があります") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| use_pattern_interrupt = st.checkbox( | |
| "パターン中断", | |
| help="""対照的な概念を組み合わせて意外性のある結果を生成します。 | |
| 通常は組み合わせられない対照的な概念や要素を意図的に混ぜ合わせて、AIの「通常の思考パターン」を中断させる技術です。 | |
| 例えば「古代の未来」「エーテルサイバーパンク」などの矛盾するコンセプトを組み合わせることで、予想外の創造的な結果を引き出します。""" | |
| ) | |
| use_logical_paradox = st.checkbox( | |
| "論理パラドックス", | |
| help="""矛盾する要素を組み合わせて創造的な表現を引き出します。 | |
| 矛盾する論理や概念を組み込むことで、AIに解決不能な「パズル」を提示し、より創造的な解釈を促す手法です。 | |
| 「上昇する落下」「冷たい炎」などの矛盾する表現を用います。""" | |
| ) | |
| with col2: | |
| use_magic_words = st.checkbox( | |
| "魔法の単語", | |
| help="""特定の「魔法の単語」を使って特殊な効果を引き出します。 | |
| MidJourney/nijiJourneyのアルゴリズムに特に強く反応する特定の単語や語句を使用する技術です。 | |
| 特定の芸術家名、美術用語、技法名など、特殊な効果を引き出す「キーワード」を戦略的に配置します。""" | |
| ) | |
| use_emotion_matrix = st.checkbox( | |
| "感情マトリックス", | |
| help="""複雑な感情表現を階層的に組み込みます。 | |
| 複数の感情を階層構造で組み込み、より微妙で複雑な感情表現を生成する技法です。 | |
| 主要感情と二次感情を組み合わせることで、「懐かしさを含んだ喜び」「好奇心を伴う恐れ」など、ニュアンスのある感情を表現します。""" | |
| ) | |
| if use_pattern_interrupt: | |
| pattern_concepts = st.text_input( | |
| "対照的な概念を入力 (コンマ区切り)", | |
| help="例: 「エーテル,サイバーパンク」「古代,未来」" | |
| ) | |
| if use_emotion_matrix: | |
| primary_emotion = st.selectbox( | |
| "主要感情", | |
| ["joy", "fear", "sadness", "anger", "surprise", "contemplative", "peaceful", "mysterious"] | |
| ) | |
| secondary_emotion = st.selectbox( | |
| "二次感情", | |
| ["hopeful", "melancholic", "anxious", "determined", "curious", "nostalgic", "dreamy", "tense"] | |
| ) | |
| # OpenAI APIキーが設定されていない場合の警告 | |
| if "o4-mini-2025-04-16" in model_options and not openai_available and model == "o4-mini-2025-04-16": | |
| st.warning("OpenAI APIキーが設定されていないため、GPTモデルは使用できません。他のモデルを選択してください。") | |
| # 生成ボタン | |
| if st.button("🚀 プロンプトを生成", type="primary", use_container_width=True): | |
| if not user_input: | |
| st.error("描きたいイメージを入力してください") | |
| elif model == "o4-mini-2025-04-16" and not openai_available: | |
| st.error("OpenAI APIキーが設定されていないため、GPTモデルは使用できません。他のモデルを選択してください。") | |
| else: | |
| with st.spinner("AIがプロンプトを生成中..."): | |
| # パラメータの準備 | |
| params = { | |
| "input": user_input, | |
| "mode": mode.lower(), | |
| "complexity": complexity, | |
| "model": model, | |
| "aspect_ratio": aspect_ratio, | |
| "quality": quality, | |
| "style": style, | |
| "stylize": stylize, | |
| "advanced": { | |
| "camera_angle": None if camera_angle == "自動選択" else camera_angle, | |
| "lens_type": None if lens_type == "自動選択" else lens_type, | |
| "lighting": None if lighting == "自動選択" else lighting, | |
| "composition": None if composition == "自動選択" else composition, | |
| "advanced_params": json.loads(advanced_params) if advanced_params else {} | |
| }, | |
| "experimental": { | |
| "pattern_interrupt": use_pattern_interrupt, | |
| "logical_paradox": use_logical_paradox, | |
| "magic_words": use_magic_words, | |
| "emotion_matrix": use_emotion_matrix | |
| } | |
| } | |
| # MidJourney特有のパラメータを追加 | |
| # スタイルリファレンス | |
| if 'use_style_reference' in locals() and use_style_reference: | |
| params["advanced"]["style_reference"] = { | |
| "use": True, | |
| "value": sref_value, | |
| "style_weight": style_weight, | |
| "style_version": style_version | |
| } | |
| # パーソナライゼーション | |
| if 'use_personalization' in locals() and use_personalization: | |
| params["advanced"]["personalization"] = { | |
| "use": True, | |
| "type": personalization_type, | |
| "value": personalization_value | |
| } | |
| # キャラクター参照 | |
| if 'use_character_reference' in locals() and use_character_reference: | |
| params["advanced"]["character_reference"] = { | |
| "use": True, | |
| "value": cref_value | |
| } | |
| # 繰り返し生成 | |
| if 'use_repeat' in locals() and use_repeat: | |
| params["advanced"]["repeat"] = { | |
| "use": True, | |
| "count": repeat_count | |
| } | |
| # 画像プロンプトの影響度 | |
| if 'use_image_weight' in locals() and use_image_weight: | |
| params["advanced"]["image_weight"] = { | |
| "use": True, | |
| "value": image_weight | |
| } | |
| # seed値 | |
| if 'use_seed' in locals() and use_seed: | |
| params["advanced"]["seed"] = { | |
| "use": True, | |
| "value": seed_value | |
| } | |
| # chaosレベル | |
| if 'use_chaos' in locals() and use_chaos: | |
| params["advanced"]["chaos"] = { | |
| "use": True, | |
| "value": chaos_value | |
| } | |
| # ネガティブプロンプト | |
| if 'use_negative_prompt' in locals() and use_negative_prompt: | |
| params["advanced"]["negative_prompt"] = { | |
| "use": True, | |
| "value": negative_prompt | |
| } | |
| # タイル機能 | |
| if 'use_tile' in locals() and use_tile: | |
| params["advanced"]["tile"] = { | |
| "use": True | |
| } | |
| # stop値 | |
| if 'use_stop' in locals() and use_stop: | |
| params["advanced"]["stop"] = { | |
| "use": True, | |
| "value": stop_value | |
| } | |
| # 生成モード | |
| if 'generation_mode' in locals() and generation_mode != "デフォルト": | |
| params["advanced"]["generation_mode"] = generation_mode | |
| # 共有設定 | |
| if 'visibility' in locals() and visibility != "デフォルト": | |
| params["advanced"]["visibility"] = visibility | |
| # 実験的機能の詳細 | |
| if use_pattern_interrupt and 'pattern_concepts' in locals() and pattern_concepts: | |
| params["experimental"]["pattern_concepts"] = [c.strip() for c in pattern_concepts.split(",")] | |
| if use_emotion_matrix and 'primary_emotion' in locals() and 'secondary_emotion' in locals(): | |
| params["experimental"]["emotions"] = { | |
| "primary": primary_emotion, | |
| "secondary": secondary_emotion | |
| } | |
| # テクニック | |
| if not auto_select and selected_techniques: | |
| params["techniques"] = selected_techniques | |
| # プロンプト生成呼び出し | |
| result = prompt_generator.generate_prompt(client, params) | |
| # 結果の解析 | |
| prompt, explanation = parse_prompt_result(result) | |
| # 結果表示 | |
| st.success("プロンプトを生成しました!") | |
| st.markdown("### 生成されたプロンプト") | |
| # プロンプトを表示 | |
| st.code(prompt, language=None) | |
| # シンプルなコピーボタン | |
| if st.button("📋 コピー", key="copy_button"): | |
| st.session_state.clipboard = prompt | |
| st.success("クリップボードにコピーしました!(Ctrl+Vで貼り付けできます)") | |
| st.caption("MidJourney/nijiJourneyにこのプロンプトを貼り付けて使用してください") | |
| # 使用したモデルの表示を追加 | |
| st.caption(f"使用モデル: **{model}**") | |
| if explanation: | |
| st.markdown("### プロンプト解説") | |
| st.markdown(explanation) | |
| # フッター | |
| st.markdown("---") | |
| st.markdown("© 2025 AI Art Prompt Generator") |