NAko3 commited on
Commit
ccc3aa1
·
verified ·
1 Parent(s): 9fad1d3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +174 -86
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import streamlit as st
2
  import json
3
  import pandas as pd
 
4
  from groq import Groq
5
  from prompt_engine import PromptGenerator
6
  from utils import load_techniques, load_styles, parse_prompt_result
@@ -73,24 +74,24 @@ st.markdown("""
73
  # サイドバー
74
  with st.sidebar:
75
  st.header("⚙️ 基本設定")
76
-
77
  mode = st.radio(
78
  "モード選択",
79
  ["MidJourney", "nijiJourney"],
80
  help="生成するプロンプトの対象となるAIツールを選択します"
81
  )
82
-
83
  complexity = st.select_slider(
84
  "複雑さレベル",
85
  options=["シンプル", "バランス", "詳細", "実験的"],
86
  value="バランス",
87
  help="生成されるプロンプトの複雑さを調整します"
88
  )
89
-
90
  # モデル選択セクションを追加
91
  st.markdown("---")
92
  st.header("🧠 AIモデル")
93
-
94
  model = st.selectbox(
95
  "Groqモデルを選択",
96
  [
@@ -103,12 +104,12 @@ with st.sidebar:
103
  index=1, # デフォルトは llama-3.3-70b-versatile
104
  help="使用するGroqのAIモデルを選択します。各モデルによって生成結果の特性が異なります"
105
  )
106
-
107
  # モデル選択時に変数を更新
108
  if model != current_model:
109
  current_model = model
110
  theme = model_themes.get(current_model, {"primary": "#4b367c", "secondary": "#d1c4e9"})
111
-
112
  # テーマの更新(実際には再読み込みが必要)
113
  st.markdown(f"""
114
  <style>
@@ -121,7 +122,7 @@ with st.sidebar:
121
  }}
122
  </style>
123
  """, unsafe_allow_html=True)
124
-
125
  # モデル情報の表示
126
  model_info = {
127
  "deepseek-r1-distill-llama-70b": "DeepSeekのLLaMA 70Bベースモデル。知識と推論能力に優れています。",
@@ -130,15 +131,15 @@ with st.sidebar:
130
  "mistral-saba-24b": "Mistral AIのSaba 24Bモデル。創造性と一貫性のバランスに優れています。",
131
  "qwen-qwq-32b": "Qwen QWQモデル。創造的な表現力が高く、芸術的プロンプトに適しています。"
132
  }
133
-
134
  st.caption(model_info.get(model, ""))
135
-
136
  st.markdown("---")
137
-
138
  st.header("🧙‍♂️ テクニック設定")
139
  auto_select = st.checkbox("テクニックを自動選択", value=True,
140
  help="オフにすると手動でテクニックを選択できます")
141
-
142
  if not auto_select:
143
  selected_techniques = st.multiselect(
144
  "使用するテクニック",
@@ -162,18 +163,18 @@ tab1, tab2, tab3, tab4 = st.tabs(["基本設定", "高度なテクニック", "
162
 
163
  with tab1:
164
  col1, col2 = st.columns(2)
165
-
166
  with col1:
167
  aspect_ratio = st.selectbox(
168
  "アスペクト比",
169
  ["1:1 (正方形)", "16:9 (横長)", "9:16 (縦長)", "3:2 (標準)", "4:3", "2:3", "カスタム"],
170
  help="画像の縦横比を設定します"
171
  )
172
-
173
  if aspect_ratio == "カスタム":
174
  custom_ratio = st.text_input("カスタム比率 (例: 5:4)")
175
  aspect_ratio = custom_ratio if custom_ratio else "1:1"
176
-
177
  quality = st.slider(
178
  "クオリティ (--q)",
179
  min_value=0.25,
@@ -182,21 +183,21 @@ with tab1:
182
  step=0.25,
183
  help="高いほど詳細な画像が生成されますが、処理時間が長くなります"
184
  )
185
-
186
  with col2:
187
  style_category = st.selectbox(
188
  "スタイルカテゴリ",
189
  list(styles.keys()),
190
  help="生成画像の基本的なスタイル方向性を選択します"
191
  )
192
-
193
  style_options = styles[style_category]
194
  style = st.selectbox(
195
  "スタイル",
196
  style_options,
197
  help="具体的なスタイルを選択します"
198
  )
199
-
200
  stylize = st.slider(
201
  "スタイル強度 (--s)",
202
  min_value=0,
@@ -211,13 +212,13 @@ with tab2:
211
  st.info("「テクニックを自動選択」がオンになっています。AIが最適なテクニックを選択します。")
212
  else:
213
  st.markdown("### 選択したテクニック")
214
-
215
  if selected_techniques:
216
  for tech in selected_techniques:
217
  st.markdown(f"**{tech}**: {techniques[tech]['description']}")
218
  else:
219
  st.warning("テクニックが選択されていません。サイドバーから選択してください。")
220
-
221
  st.markdown("### テクニック解説")
222
  tech_df = pd.DataFrame({
223
  "テクニック": list(techniques.keys()),
@@ -228,9 +229,9 @@ with tab2:
228
 
229
  with tab3:
230
  st.markdown("### 専門家向け設定")
231
-
232
  col1, col2 = st.columns(2)
233
-
234
  with col1:
235
  camera_angle = st.selectbox(
236
  "カメラアングル",
@@ -243,7 +244,7 @@ with tab3:
243
  - aerial view(空撮視点): 高い位置から真���を見下ろす視点。広大な風景や複雑なシーンの全体像を捉え、鳥の目線で世界を見せます。
244
  - worm's eye view(ワームズアイビュー): 極端な低アングルで、まるで地面のミミズの視点から見上げるような角度。被写体の壮大さや圧倒的な存在感を強調します。"""
245
  )
246
-
247
  lens_type = st.selectbox(
248
  "レンズタイプ",
249
  ["自動選択", "wide angle", "telephoto", "macro", "fisheye", "tilt-shift", "normal"],
@@ -255,7 +256,7 @@ with tab3:
255
  - tilt-shift(ティルトシフトレンズ): レンズの角度や位置を調整できる特殊なレンズ。ミニチュア効果(実物を模型のように見せる)や、遠近法の調整、建築物の垂直線を修正する効果があります。
256
  - normal(標準レンズ): 人間の視野に近い自然な画角を持つレンズ。歪みが少なく、最も現実に近い見え方を再現します。一般的に50mm前後の焦点距離を持ちます。"""
257
  )
258
-
259
  with col2:
260
  lighting = st.selectbox(
261
  "照明設定",
@@ -268,7 +269,7 @@ with tab3:
268
  - backlight(バックライト): 被写体の後ろから当てる光。シルエットや輪郭を強調し、被写体の周りに光の縁取り(リムライト)を作ります。神秘的で幻想的な雰囲気や、逆光による独特の効果を生み出します。
269
  - studio lighting(スタジオライティング): 制御された環境での複数の人工光源を使った照明技術。精密なハイライトとシャドウのコントロールが可能で、商業写真やポートレートに用いられます。"""
270
  )
271
-
272
  composition = st.selectbox(
273
  "構図",
274
  ["自動選択", "rule of thirds", "golden ratio", "symmetrical", "asymmetrical", "leading lines", "frame within frame"],
@@ -280,23 +281,23 @@ with tab3:
280
  - leading lines(リーディングライン): 道路、鉄道、川などの線状の要素を使って視線を画像内の特定の場所(通常は主題)へと導く構図。写真に奥行きと方向性を与え、視聴者の目の動きをコントロールします。
281
  - frame within frame(フレームインフレーム): 窓、アーチ、木の枝などの要素を使って、画像内に別のフレームを作り出す構図。主題を強調し、奥行きを加え、視聴者の視線を中心に導きます。"""
282
  )
283
-
284
  # MidJourney特有のパラメータセクションを追加
285
  st.markdown("### MidJourney/nijiJourney特有のパラメータ")
286
-
287
  # タブでパラメータをカテゴリ分け
288
  param_tab1, param_tab2, param_tab3 = st.tabs(["スタイル参照", "パーソナライズ", "その他"])
289
-
290
  with param_tab1:
291
  # スタイルリファレンス (--sref) 設定
292
  use_style_reference = st.checkbox("スタイルリファレンス (--sref) を使用",
293
  help="""別画像のスタイルを参照し、色調や質感を新規生成に適用します。
294
  特定の画像のスタイル特性(色調、テクスチャ、画風など)を参照して新しい画像に適用するパラメータです。
295
  特定の画像URL、ランダム選択、または以前に生成した画像のコードを指定できます。""")
296
-
297
  if use_style_reference:
298
  sref_type = st.radio("参照方法", ["ランダム", "画像URL", "コード指定"], horizontal=True)
299
-
300
  if sref_type == "ランダム":
301
  st.info("ランダムに選ばれたスタイルが適用されます (--sref random)")
302
  sref_value = "random"
@@ -304,29 +305,29 @@ with tab3:
304
  sref_value = st.text_input("画像URL", help="スタイル参照する画像のURLを入力してください")
305
  else:
306
  sref_value = st.text_input("スタイルコード", help="以前生成されたsrefコードを入力 (例: 1234567)")
307
-
308
  # スタイルウェイト
309
  style_weight = st.slider("スタイルウェイト (--sw)", 0, 1000, 100,
310
  help="""参照画像の影響度を調整します。高いほど強く反映されます。
311
  参照画像のスタイルがどの程度強く新しい画像に影響するかを0〜1000の値で指定します。
312
  値が高いほど参照スタイルの影響が強くなります。""")
313
-
314
  # スタイルバージョン
315
  style_version = st.radio("スタイルバージョン (--sv)", [1, 2, 3, 4], index=3, horizontal=True,
316
  help="""Style Referenceアルゴリズム���バージョンを選択します。
317
  スタイル参照アルゴリズムのバージョン(1〜4)を選択します。
318
  新しいバージョンほど改良されていますが、それぞれ異なる特性を持っています。""")
319
-
320
  with param_tab2:
321
  # パーソナライゼーション (--p) 設定
322
  use_personalization = st.checkbox("パーソナライゼーション (--p) を使用",
323
  help="""自身の好みに学習させたプロファイルを適用します。
324
  ユーザーの好みに基づいて学習されたカスタムプロファイルを適用するパラメータです。
325
  デフォルトプロファイル、特定のプロファイルID、または以前生成したコードを指定できます。""")
326
-
327
  if use_personalization:
328
  personalization_type = st.radio("適用方法", ["デフォルト", "プロファイルID", "コード指定"], horizontal=True)
329
-
330
  if personalization_type == "デフォルト":
331
  st.info("設定済みのデフォルトプロファイルが適用されます (--p)")
332
  personalization_value = ""
@@ -334,40 +335,57 @@ with tab3:
334
  personalization_value = st.text_input("プロファイルID", help="使用するプロファイルIDを入力")
335
  else:
336
  personalization_value = st.text_input("パーソナライズコード", help="以前生成されたコードを入力")
337
-
338
  # パーソナライズ強度は --stylize を共用
339
  st.caption("パーソナライズの適用度はスタイル強度 (--s) パラメータで調整されます")
340
-
341
  with param_tab3:
342
  # その他のパラメータ
343
  col1, col2 = st.columns(2)
344
-
345
  with col1:
346
  use_character_reference = st.checkbox("キャラクター参照 (--cref)",
347
  help="""複数シーンで同一キャラクターを維持します。
348
  特定のキャラクターの外見を維持しながら複数の画像を生成するためのパラメータです。
349
  キャラクターが写っている参照画像のURLを指定します。""")
350
-
351
  if use_character_reference:
352
  cref_value = st.text_input("キャラクター参照URL", help="キャラクターが写っている画像のURLを入力")
353
-
354
  use_repeat = st.checkbox("繰り返し生成 (--repeat / --r)",
355
  help="""同一プロンプトで複数グリッドを生成します。
356
  同じプロンプトで複数セットの画像を連続して生成するパラメータです。
357
  時間を節約し、より多くのバリエーションを効率的に探索できます。""")
358
-
359
  if use_repeat:
360
  repeat_count = st.number_input("繰り返し回数", min_value=1, max_value=10, value=2)
361
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  with col2:
363
  use_image_weight = st.checkbox("画像プロンプトの影響度 (--iw)",
364
  help="""画像プロンプト(イメージURL)の影響度を調整します。
365
  画像プロンプト(URLで提供される参照画像)が��終結果にどれだけ影響するかを0.0〜2.0の値で指定します。
366
  高い値ほど画像プロンプトの影響が強くなります。""")
367
-
368
  if use_image_weight:
369
  image_weight = st.slider("画像ウェイト", 0.0, 2.0, 1.0, 0.1)
370
-
371
  generation_mode = st.radio("生成モード",
372
  ["デフォルト", "fast", "relax", "turbo", "draft"],
373
  index=0, horizontal=True,
@@ -376,14 +394,51 @@ with tab3:
376
  - relax(リラックスモード): 通常より低い優先度で処理される低コストのモード。急ぎでない場合や、サーバー負荷が高い時間帯に適しています。
377
  - turbo(ターボモード): 最も高速なモードで、数秒で結果を生成します。品質は最も低くなりますが、概念実証や迅速なアイデア検証に最適です。
378
  - draft(ドラフトモード): より低解像度で高速に生成するモード。迅速なイテレーションに適していますが、最終的な高品質画像には向いていません。""")
379
-
380
  visibility = st.radio("共有設定",
381
  ["デフォルト", "public", "stealth"],
382
  index=0, horizontal=True,
383
  help="""MidJourneyサイトへの公開/非公開を制御:
384
  - public(公開): 生成した画像をMidJourneyのコミュニティギャラリーに公開します。他のユーザーが閲覧でき、コミュニティの参考になります。
385
  - stealth(非公開): 生成した画像を非公開にします。他のユーザーには表示されず、完全にプライベートに保たれます。""")
386
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
  # カスタムパラメータセクション
388
  st.markdown("### カスタムパラメータ")
389
  advanced_params = st.text_area(
@@ -395,9 +450,9 @@ with tab3:
395
  with tab4:
396
  st.markdown("### 実験的機能")
397
  st.warning("これらの機能は予測不能な結果をもたらす可能性があります")
398
-
399
  col1, col2 = st.columns(2)
400
-
401
  with col1:
402
  use_pattern_interrupt = st.checkbox(
403
  "パターン中断",
@@ -405,14 +460,14 @@ with tab4:
405
  通常は組み合わせられない対照的な概念や要素を意図的に混ぜ合わせて、AIの「通常の思考パターン」を中断させる技術です。
406
  例えば「古代の未来」「エーテルサイバーパンク」などの矛盾するコンセプトを組み合わせることで、予想外の創造的な結果を引き出します。"""
407
  )
408
-
409
  use_logical_paradox = st.checkbox(
410
  "論理パラドックス",
411
  help="""矛盾する要素を組み合わせて創造的な表現を引き出します。
412
  矛盾する論理や概念を組み込むことで、AIに解決不能な「パズル」を提示し、より創造的な解釈を促す手法です。
413
  「上昇する落下」「冷たい炎」などの矛盾する表現を用います。"""
414
  )
415
-
416
  with col2:
417
  use_magic_words = st.checkbox(
418
  "魔法の単語",
@@ -420,20 +475,20 @@ with tab4:
420
  MidJourney/nijiJourneyのアルゴリズムに特に強く反応する特定の単語や語句を使用する技術です。
421
  特定の芸術家名、美術用語、技法名など、特殊な効果を引き出す「キーワード」を戦略的に配置します。"""
422
  )
423
-
424
  use_emotion_matrix = st.checkbox(
425
  "感情マトリックス",
426
  help="""複雑な感情表現を階層的に組み込みます。
427
  複数の感情を階層構造で組み込み、より微妙で複雑な感情表現を生成する技法です。
428
  主要感情と二次感情を組み合わせることで、「懐かしさを含んだ喜び」「好奇心を伴う恐れ」など、ニュアンスのある感情を表現します。"""
429
  )
430
-
431
  if use_pattern_interrupt:
432
  pattern_concepts = st.text_input(
433
  "対照的な概念を入力 (コンマ区切り)",
434
  help="例: 「エーテル,サイバーパンク」「古代,未来」"
435
  )
436
-
437
  if use_emotion_matrix:
438
  primary_emotion = st.selectbox(
439
  "主要感情",
@@ -474,9 +529,9 @@ if st.button("🚀 プロンプトを生成", type="primary", use_container_widt
474
  "emotion_matrix": use_emotion_matrix
475
  }
476
  }
477
-
478
  # MidJourney特有のパラメータを追加
479
-
480
  # スタイルリファレンス
481
  if 'use_style_reference' in locals() and use_style_reference:
482
  params["advanced"]["style_reference"] = {
@@ -485,7 +540,7 @@ if st.button("🚀 プロンプトを生成", type="primary", use_container_widt
485
  "style_weight": style_weight,
486
  "style_version": style_version
487
  }
488
-
489
  # パーソナライゼーション
490
  if 'use_personalization' in locals() and use_personalization:
491
  params["advanced"]["personalization"] = {
@@ -493,100 +548,133 @@ if st.button("🚀 プロンプトを生成", type="primary", use_container_widt
493
  "type": personalization_type,
494
  "value": personalization_value
495
  }
496
-
497
  # キャラクター参照
498
  if 'use_character_reference' in locals() and use_character_reference:
499
  params["advanced"]["character_reference"] = {
500
  "use": True,
501
  "value": cref_value
502
  }
503
-
504
  # 繰り返し生成
505
  if 'use_repeat' in locals() and use_repeat:
506
  params["advanced"]["repeat"] = {
507
  "use": True,
508
  "count": repeat_count
509
  }
510
-
511
  # 画像プロンプトの影響度
512
  if 'use_image_weight' in locals() and use_image_weight:
513
  params["advanced"]["image_weight"] = {
514
  "use": True,
515
  "value": image_weight
516
  }
517
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  # 生成モード
519
  if 'generation_mode' in locals() and generation_mode != "デフォルト":
520
  params["advanced"]["generation_mode"] = generation_mode
521
-
522
  # 共有設定
523
  if 'visibility' in locals() and visibility != "デフォルト":
524
  params["advanced"]["visibility"] = visibility
525
-
526
  # 実験的機能の詳細
527
  if use_pattern_interrupt and 'pattern_concepts' in locals() and pattern_concepts:
528
  params["experimental"]["pattern_concepts"] = [c.strip() for c in pattern_concepts.split(",")]
529
-
530
  if use_emotion_matrix and 'primary_emotion' in locals() and 'secondary_emotion' in locals():
531
  params["experimental"]["emotions"] = {
532
  "primary": primary_emotion,
533
  "secondary": secondary_emotion
534
  }
535
-
536
  # テクニック
537
  if not auto_select and selected_techniques:
538
  params["techniques"] = selected_techniques
539
-
540
  # プロンプト生成呼び出し
541
  result = prompt_generator.generate_prompt(client, params)
542
-
543
  # 結果の解析
544
  prompt, explanation = parse_prompt_result(result)
545
-
546
  # 結果表示
547
  st.success("プロンプトを生成しました!")
548
-
549
  st.markdown("### 生成されたプロンプト")
550
-
551
  # まずプロンプトを表示
552
  st.code(prompt, language=None)
553
-
554
- # JavaScript実装を修正 - バックスラッシュの問題を解決
555
- prompt_escaped = prompt.replace("`", "\\`").replace("'", "\\'")
556
- js_code = """
557
  <script>
558
- function copyToClipboard() {
559
- const text = `""" + prompt_escaped + """`;
560
- navigator.clipboard.writeText(text).then(function() {
561
  document.getElementById('copy-status').innerHTML = "コピーしました!";
562
- setTimeout(function() {
563
  document.getElementById('copy-status').innerHTML = "";
564
- }, 2000);
565
- })
566
- .catch(function(error) {
567
  document.getElementById('copy-status').innerHTML = "コピーできませんでした: " + error;
568
- });
569
- }
570
  </script>
571
  <button
572
  onclick="copyToClipboard()"
573
- style="background-color:""" + theme["primary"] + """; color:white; border:none; padding:8px 16px; border-radius:4px; cursor:pointer;"
574
  >
575
  📋 クリップボードにコピー
576
  </button>
577
  <span id="copy-status" style="margin-left:10px; color:green;"></span>
578
  """
579
  st.markdown(js_code, unsafe_allow_html=True)
580
-
581
  st.caption("MidJourney/nijiJourneyにこのプロンプトを貼り付けて使用してください")
582
-
583
  # 使用したモデルの表示を追加
584
  st.caption(f"使用モデル: **{model}**")
585
-
586
  if explanation:
587
  st.markdown("### プロンプト解説")
588
  st.markdown(explanation)
589
 
590
  # フッター
591
  st.markdown("---")
592
- st.markdown("© 2025 AI Art Prompt Generator")
 
1
  import streamlit as st
2
  import json
3
  import pandas as pd
4
+ import random
5
  from groq import Groq
6
  from prompt_engine import PromptGenerator
7
  from utils import load_techniques, load_styles, parse_prompt_result
 
74
  # サイドバー
75
  with st.sidebar:
76
  st.header("⚙️ 基本設定")
77
+
78
  mode = st.radio(
79
  "モード選択",
80
  ["MidJourney", "nijiJourney"],
81
  help="生成するプロンプトの対象となるAIツールを選択します"
82
  )
83
+
84
  complexity = st.select_slider(
85
  "複雑さレベル",
86
  options=["シンプル", "バランス", "詳細", "実験的"],
87
  value="バランス",
88
  help="生成されるプロンプトの複雑さを調整します"
89
  )
90
+
91
  # モデル選択セクションを追加
92
  st.markdown("---")
93
  st.header("🧠 AIモデル")
94
+
95
  model = st.selectbox(
96
  "Groqモデルを選択",
97
  [
 
104
  index=1, # デフォルトは llama-3.3-70b-versatile
105
  help="使用するGroqのAIモデルを選択します。各モデルによって生成結果の特性が異なります"
106
  )
107
+
108
  # モデル選択時に変数を更新
109
  if model != current_model:
110
  current_model = model
111
  theme = model_themes.get(current_model, {"primary": "#4b367c", "secondary": "#d1c4e9"})
112
+
113
  # テーマの更新(実際には再読み込みが必要)
114
  st.markdown(f"""
115
  <style>
 
122
  }}
123
  </style>
124
  """, unsafe_allow_html=True)
125
+
126
  # モデル情報の表示
127
  model_info = {
128
  "deepseek-r1-distill-llama-70b": "DeepSeekのLLaMA 70Bベースモデル。知識と推論能力に優れています。",
 
131
  "mistral-saba-24b": "Mistral AIのSaba 24Bモデル。創造性と一貫性のバランスに優れています。",
132
  "qwen-qwq-32b": "Qwen QWQモデル。創造的な表現力が高く、芸術的プロンプトに適しています。"
133
  }
134
+
135
  st.caption(model_info.get(model, ""))
136
+
137
  st.markdown("---")
138
+
139
  st.header("🧙‍♂️ テクニック設定")
140
  auto_select = st.checkbox("テクニックを自動選択", value=True,
141
  help="オフにすると手動でテクニックを選択できます")
142
+
143
  if not auto_select:
144
  selected_techniques = st.multiselect(
145
  "使用するテクニック",
 
163
 
164
  with tab1:
165
  col1, col2 = st.columns(2)
166
+
167
  with col1:
168
  aspect_ratio = st.selectbox(
169
  "アスペクト比",
170
  ["1:1 (正方形)", "16:9 (横長)", "9:16 (縦長)", "3:2 (標準)", "4:3", "2:3", "カスタム"],
171
  help="画像の縦横比を設定します"
172
  )
173
+
174
  if aspect_ratio == "カスタム":
175
  custom_ratio = st.text_input("カスタム比率 (例: 5:4)")
176
  aspect_ratio = custom_ratio if custom_ratio else "1:1"
177
+
178
  quality = st.slider(
179
  "クオリティ (--q)",
180
  min_value=0.25,
 
183
  step=0.25,
184
  help="高いほど詳細な画像が生成されますが、処理時間が長くなります"
185
  )
186
+
187
  with col2:
188
  style_category = st.selectbox(
189
  "スタイルカテゴリ",
190
  list(styles.keys()),
191
  help="生成画像の基本的なスタイル方向性を選択します"
192
  )
193
+
194
  style_options = styles[style_category]
195
  style = st.selectbox(
196
  "スタイル",
197
  style_options,
198
  help="具体的なスタイルを選択します"
199
  )
200
+
201
  stylize = st.slider(
202
  "スタイル強度 (--s)",
203
  min_value=0,
 
212
  st.info("「テクニックを自動選択」がオンになっています。AIが最適なテクニックを選択します。")
213
  else:
214
  st.markdown("### 選択したテクニック")
215
+
216
  if selected_techniques:
217
  for tech in selected_techniques:
218
  st.markdown(f"**{tech}**: {techniques[tech]['description']}")
219
  else:
220
  st.warning("テクニックが選択されていません。サイドバーから選択してください。")
221
+
222
  st.markdown("### テクニック解説")
223
  tech_df = pd.DataFrame({
224
  "テクニック": list(techniques.keys()),
 
229
 
230
  with tab3:
231
  st.markdown("### 専門家向け設定")
232
+
233
  col1, col2 = st.columns(2)
234
+
235
  with col1:
236
  camera_angle = st.selectbox(
237
  "カメラアングル",
 
244
  - aerial view(空撮視点): 高い位置から真���を見下ろす視点。広大な風景や複雑なシーンの全体像を捉え、鳥の目線で世界を見せます。
245
  - worm's eye view(ワームズアイビュー): 極端な低アングルで、まるで地面のミミズの視点から見上げるような角度。被写体の壮大さや圧倒的な存在感を強調します。"""
246
  )
247
+
248
  lens_type = st.selectbox(
249
  "レンズタイプ",
250
  ["自動選択", "wide angle", "telephoto", "macro", "fisheye", "tilt-shift", "normal"],
 
256
  - tilt-shift(ティルトシフトレンズ): レンズの角度や位置を調整できる特殊なレンズ。ミニチュア効果(実物を模型のように見せる)や、遠近法の調整、建築物の垂直線を修正する効果があります。
257
  - normal(標準レンズ): 人間の視野に近い自然な画角を持つレンズ。歪みが少なく、最も現実に近い見え方を再現します。一般的に50mm前後の焦点距離を持ちます。"""
258
  )
259
+
260
  with col2:
261
  lighting = st.selectbox(
262
  "照明設定",
 
269
  - backlight(バックライト): 被写体の後ろから当てる光。シルエットや輪郭を強調し、被写体の周りに光の縁取り(リムライト)を作ります。神秘的で幻想的な雰囲気や、逆光による独特の効果を生み出します。
270
  - studio lighting(スタジオライティング): 制御された環境での複数の人工光源を使った照明技術。精密なハイライトとシャドウのコントロールが可能で、商業写真やポートレートに用いられます。"""
271
  )
272
+
273
  composition = st.selectbox(
274
  "構図",
275
  ["自動選択", "rule of thirds", "golden ratio", "symmetrical", "asymmetrical", "leading lines", "frame within frame"],
 
281
  - leading lines(リーディングライン): 道路、鉄道、川などの線状の要素を使って視線を画像内の特定の場所(通常は主題)へと導く構図。写真に奥行きと方向性を与え、視聴者の目の動きをコントロールします。
282
  - frame within frame(フレームインフレーム): 窓、アーチ、木の枝などの要素を使って、画像内に別のフレームを作り出す構図。主題を強調し、奥行きを加え、視聴者の視線を中心に導きます。"""
283
  )
284
+
285
  # MidJourney特有のパラメータセクションを追加
286
  st.markdown("### MidJourney/nijiJourney特有のパラメータ")
287
+
288
  # タブでパラメータをカテゴリ分け
289
  param_tab1, param_tab2, param_tab3 = st.tabs(["スタイル参照", "パーソナライズ", "その他"])
290
+
291
  with param_tab1:
292
  # スタイルリファレンス (--sref) 設定
293
  use_style_reference = st.checkbox("スタイルリファレンス (--sref) を使用",
294
  help="""別画像のスタイルを参照し、色調や質感を新規生成に適用します。
295
  特定の画像のスタイル特性(色調、テクスチャ、画風など)を参照して新しい画像に適用するパラメータです。
296
  特定の画像URL、ランダム選択、または以前に生成した画像のコードを指定できます。""")
297
+
298
  if use_style_reference:
299
  sref_type = st.radio("参照方法", ["ランダム", "画像URL", "コード指定"], horizontal=True)
300
+
301
  if sref_type == "ランダム":
302
  st.info("ランダムに選ばれたスタイルが適用されます (--sref random)")
303
  sref_value = "random"
 
305
  sref_value = st.text_input("画像URL", help="スタイル参照する画像のURLを入力してください")
306
  else:
307
  sref_value = st.text_input("スタイルコード", help="以前生成されたsrefコードを入力 (例: 1234567)")
308
+
309
  # スタイルウェイト
310
  style_weight = st.slider("スタイルウェイト (--sw)", 0, 1000, 100,
311
  help="""参照画像の影響度を調整します。高いほど強く反映されます。
312
  参照画像のスタイルがどの程度強く新しい画像に影響するかを0〜1000の値で指定します。
313
  値が高いほど参照スタイルの影響が強くなります。""")
314
+
315
  # スタイルバージョン
316
  style_version = st.radio("スタイルバージョン (--sv)", [1, 2, 3, 4], index=3, horizontal=True,
317
  help="""Style Referenceアルゴリズム���バージョンを選択します。
318
  スタイル参照アルゴリズムのバージョン(1〜4)を選択します。
319
  新しいバージョンほど改良されていますが、それぞれ異なる特性を持っています。""")
320
+
321
  with param_tab2:
322
  # パーソナライゼーション (--p) 設定
323
  use_personalization = st.checkbox("パーソナライゼーション (--p) を使用",
324
  help="""自身の好みに学習させたプロファイルを適用します。
325
  ユーザーの好みに基づいて学習されたカスタムプロファイルを適用するパラメータです。
326
  デフォルトプロファイル、特定のプロファイルID、または以前生成したコードを指定できます。""")
327
+
328
  if use_personalization:
329
  personalization_type = st.radio("適用方法", ["デフォルト", "プロファイルID", "コード指定"], horizontal=True)
330
+
331
  if personalization_type == "デフォルト":
332
  st.info("設定済みのデフォルトプロファイルが適用されます (--p)")
333
  personalization_value = ""
 
335
  personalization_value = st.text_input("プロファイルID", help="使用するプロファイルIDを入力")
336
  else:
337
  personalization_value = st.text_input("パーソナライズコード", help="以前生成されたコードを入力")
338
+
339
  # パーソナライズ強度は --stylize を共用
340
  st.caption("パーソナライズの適用度はスタイル強度 (--s) パラメータで調整されます")
341
+
342
  with param_tab3:
343
  # その他のパラメータ
344
  col1, col2 = st.columns(2)
345
+
346
  with col1:
347
  use_character_reference = st.checkbox("キャラクター参照 (--cref)",
348
  help="""複数シーンで同一キャラクターを維持します。
349
  特定のキャラクターの外見を維持しながら複数の画像を生成するためのパラメータです。
350
  キャラクターが写っている参照画像のURLを指定します。""")
351
+
352
  if use_character_reference:
353
  cref_value = st.text_input("キャラクター参照URL", help="キャラクターが写っている画像のURLを入力")
354
+
355
  use_repeat = st.checkbox("繰り返し生成 (--repeat / --r)",
356
  help="""同一プロンプトで複数グリッドを生成します。
357
  同じプロンプトで複数セットの画像を連続して生成するパラメータです。
358
  時間を節約し、より多くのバリエーションを効率的に探索できます。""")
359
+
360
  if use_repeat:
361
  repeat_count = st.number_input("繰り返し回数", min_value=1, max_value=10, value=2)
362
+
363
+ # ネガティブプロンプト追加
364
+ use_negative_prompt = st.checkbox("ネガティブプロンプト (--no)",
365
+ help="""画像から除外したい要素を指定します。
366
+ 生成画像に含めたくない要素を指定するパラメータです。
367
+ 「bad hands」「text」「watermark」などの不要な要素を除外できます。""")
368
+
369
+ if use_negative_prompt:
370
+ negative_prompt = st.text_area("除外要素(コンマ区切り)",
371
+ placeholder="例: text, watermark, bad hands, blurry",
372
+ help="生成画像に含めたくない要素をコンマ区切りで入力")
373
+
374
+ # タイル機能追加
375
+ use_tile = st.checkbox("タイル生成 (--tile)",
376
+ help="""シームレスに繰り返し可能なタイル模様を生成します。
377
+ シームレスに繰り返し使用できるパターンやテクスチャを生成するためのパラメータです。
378
+ ウェブサイトの背景、壁紙、テキスタイル等に適しています。""")
379
+
380
  with col2:
381
  use_image_weight = st.checkbox("画像プロンプトの影響度 (--iw)",
382
  help="""画像プロンプト(イメージURL)の影響度を調整します。
383
  画像プロンプト(URLで提供される参照画像)が��終結果にどれだけ影響するかを0.0〜2.0の値で指定します。
384
  高い値ほど画像プロンプトの影響が強くなります。""")
385
+
386
  if use_image_weight:
387
  image_weight = st.slider("画像ウェイト", 0.0, 2.0, 1.0, 0.1)
388
+
389
  generation_mode = st.radio("生成モード",
390
  ["デフォルト", "fast", "relax", "turbo", "draft"],
391
  index=0, horizontal=True,
 
394
  - relax(リラックスモード): 通常より低い優先度で処理される低コストのモード。急ぎでない場合や、サーバー負荷が高い時間帯に適しています。
395
  - turbo(ターボモード): 最も高速なモードで、数秒で結果を生成します。品質は最も低くなりますが、概念実証や迅速なアイデア検証に最適です。
396
  - draft(ドラフトモード): より低解像度で高速に生成するモード。迅速なイテレーションに適していますが、最終的な高品質画像には向いていません。""")
397
+
398
  visibility = st.radio("共有設定",
399
  ["デフォルト", "public", "stealth"],
400
  index=0, horizontal=True,
401
  help="""MidJourneyサイトへの公開/非公開を制御:
402
  - public(公開): 生成した画像をMidJourneyのコミュニティギャラリーに公開します。他のユーザーが閲覧でき、コミュニティの参考になります。
403
  - stealth(非公開): 生成した画像を非公開にします。他のユーザーには表示されず、完全にプライベートに保たれます。""")
404
+
405
+ # seed値追加
406
+ use_seed = st.checkbox("シード値を指定 (--seed)",
407
+ help="""同じ結果を再現するための値を設定します。
408
+ 生成プロセスを制御する数値シードを指定するパラメータです。
409
+ 同じシード値を使用すると同じ条件で同様の結果を再現できます。""")
410
+
411
+ if use_seed:
412
+ seed_value = st.number_input("シード値",
413
+ min_value=0,
414
+ max_value=4294967295,
415
+ value=random.randint(0, 4294967295),
416
+ help="特定のシード値を使用して再現性を確保します")
417
+ random_seed = st.button("ランダムなシード値を生成")
418
+ if random_seed:
419
+ seed_value = random.randint(0, 4294967295)
420
+ st.write(f"生成されたシード値: {seed_value}")
421
+
422
+ # chaosレベル追加
423
+ use_chaos = st.checkbox("ランダム性設定 (--c/--chaos)",
424
+ help="""結果の予測不能さを調整します。
425
+ 生成結果の多様性やランダム性を0〜100の値で調整するパラメータです。
426
+ 高い値ほど予測不能で創造的な結果が得られますが、プロンプトからの逸脱も大きくなります。""")
427
+
428
+ if use_chaos:
429
+ chaos_value = st.slider("Chaosレベル", 0, 100, 0,
430
+ help="高いほど予測不能な結果になります")
431
+
432
+ # stop値追加
433
+ use_stop = st.checkbox("途中停止 (--stop)",
434
+ help="""生成過程を途中で停止させてラフな結果を得ます。
435
+ 生成プロセスを途中で意図的に停止させて中間結果を取得するパラメータです。
436
+ より未完成で実験的、アーティスティックな表現に適しています。""")
437
+
438
+ if use_stop:
439
+ stop_value = st.slider("停止ポイント", 10, 100, 100,
440
+ help="生成プロセスをどの段階で停止するか (%)")
441
+
442
  # カスタムパラメータセクション
443
  st.markdown("### カスタムパラメータ")
444
  advanced_params = st.text_area(
 
450
  with tab4:
451
  st.markdown("### 実験的機能")
452
  st.warning("これらの機能は予測不能な結果をもたらす可能性があります")
453
+
454
  col1, col2 = st.columns(2)
455
+
456
  with col1:
457
  use_pattern_interrupt = st.checkbox(
458
  "パターン中断",
 
460
  通常は組み合わせられない対照的な概念や要素を意図的に混ぜ合わせて、AIの「通常の思考パターン」を中断させる技術です。
461
  例えば「古代の未来」「エーテルサイバーパンク」などの矛盾するコンセプトを組み合わせることで、予想外の創造的な結果を引き出します。"""
462
  )
463
+
464
  use_logical_paradox = st.checkbox(
465
  "論理パラドックス",
466
  help="""矛盾する要素を組み合わせて創造的な表現を引き出します。
467
  矛盾する論理や概念を組み込むことで、AIに解決不能な「パズル」を提示し、より創造的な解釈を促す手法です。
468
  「上昇する落下」「冷たい炎」などの矛盾する表現を用います。"""
469
  )
470
+
471
  with col2:
472
  use_magic_words = st.checkbox(
473
  "魔法の単語",
 
475
  MidJourney/nijiJourneyのアルゴリズムに特に強く反応する特定の単語や語句を使用する技術です。
476
  特定の芸術家名、美術用語、技法名など、特殊な効果を引き出す「キーワード」を戦略的に配置します。"""
477
  )
478
+
479
  use_emotion_matrix = st.checkbox(
480
  "感情マトリックス",
481
  help="""複雑な感情表現を階層的に組み込みます。
482
  複数の感情を階層構造で組み込み、より微妙で複雑な感情表現を生成する技法です。
483
  主要感情と二次感情を組み合わせることで、「懐かしさを含んだ喜び」「好奇心を伴う恐れ」など、ニュアンスのある感情を表現します。"""
484
  )
485
+
486
  if use_pattern_interrupt:
487
  pattern_concepts = st.text_input(
488
  "対照的な概念を入力 (コンマ区切り)",
489
  help="例: 「エーテル,サイバーパンク」「古代,未来」"
490
  )
491
+
492
  if use_emotion_matrix:
493
  primary_emotion = st.selectbox(
494
  "主要感情",
 
529
  "emotion_matrix": use_emotion_matrix
530
  }
531
  }
532
+
533
  # MidJourney特有のパラメータを追加
534
+
535
  # スタイルリファレンス
536
  if 'use_style_reference' in locals() and use_style_reference:
537
  params["advanced"]["style_reference"] = {
 
540
  "style_weight": style_weight,
541
  "style_version": style_version
542
  }
543
+
544
  # パーソナライゼーション
545
  if 'use_personalization' in locals() and use_personalization:
546
  params["advanced"]["personalization"] = {
 
548
  "type": personalization_type,
549
  "value": personalization_value
550
  }
551
+
552
  # キャラクター参照
553
  if 'use_character_reference' in locals() and use_character_reference:
554
  params["advanced"]["character_reference"] = {
555
  "use": True,
556
  "value": cref_value
557
  }
558
+
559
  # 繰り返し生成
560
  if 'use_repeat' in locals() and use_repeat:
561
  params["advanced"]["repeat"] = {
562
  "use": True,
563
  "count": repeat_count
564
  }
565
+
566
  # 画像プロンプトの影響度
567
  if 'use_image_weight' in locals() and use_image_weight:
568
  params["advanced"]["image_weight"] = {
569
  "use": True,
570
  "value": image_weight
571
  }
572
+
573
+ # seed値
574
+ if 'use_seed' in locals() and use_seed:
575
+ params["advanced"]["seed"] = {
576
+ "use": True,
577
+ "value": seed_value
578
+ }
579
+
580
+ # chaosレベル
581
+ if 'use_chaos' in locals() and use_chaos:
582
+ params["advanced"]["chaos"] = {
583
+ "use": True,
584
+ "value": chaos_value
585
+ }
586
+
587
+ # ネガティブプロンプト
588
+ if 'use_negative_prompt' in locals() and use_negative_prompt:
589
+ params["advanced"]["negative_prompt"] = {
590
+ "use": True,
591
+ "value": negative_prompt
592
+ }
593
+
594
+ # タイル機能
595
+ if 'use_tile' in locals() and use_tile:
596
+ params["advanced"]["tile"] = {
597
+ "use": True
598
+ }
599
+
600
+ # stop値
601
+ if 'use_stop' in locals() and use_stop:
602
+ params["advanced"]["stop"] = {
603
+ "use": True,
604
+ "value": stop_value
605
+ }
606
+
607
  # 生成モード
608
  if 'generation_mode' in locals() and generation_mode != "デフォルト":
609
  params["advanced"]["generation_mode"] = generation_mode
610
+
611
  # 共有設定
612
  if 'visibility' in locals() and visibility != "デフォルト":
613
  params["advanced"]["visibility"] = visibility
614
+
615
  # 実験的機能の詳細
616
  if use_pattern_interrupt and 'pattern_concepts' in locals() and pattern_concepts:
617
  params["experimental"]["pattern_concepts"] = [c.strip() for c in pattern_concepts.split(",")]
618
+
619
  if use_emotion_matrix and 'primary_emotion' in locals() and 'secondary_emotion' in locals():
620
  params["experimental"]["emotions"] = {
621
  "primary": primary_emotion,
622
  "secondary": secondary_emotion
623
  }
624
+
625
  # テクニック
626
  if not auto_select and selected_techniques:
627
  params["techniques"] = selected_techniques
628
+
629
  # プロンプト生成呼び出し
630
  result = prompt_generator.generate_prompt(client, params)
631
+
632
  # 結果の解析
633
  prompt, explanation = parse_prompt_result(result)
634
+
635
  # 結果表示
636
  st.success("プロンプトを生成しました!")
637
+
638
  st.markdown("### 生成されたプロンプト")
639
+
640
  # まずプロンプトを表示
641
  st.code(prompt, language=None)
642
+
643
+ # JavaScriptを使ったコピー機能の正しい実装
644
+ js_code = f"""
 
645
  <script>
646
+ function copyToClipboard() {{
647
+ const text = `{prompt.replace("`", "\\`").replace("'", "\\'")}`;
648
+ navigator.clipboard.writeText(text).then(function() {{
649
  document.getElementById('copy-status').innerHTML = "コピーしました!";
650
+ setTimeout(function() {{
651
  document.getElementById('copy-status').innerHTML = "";
652
+ }}, 2000);
653
+ }})
654
+ .catch(function(error) {{
655
  document.getElementById('copy-status').innerHTML = "コピーできませんでした: " + error;
656
+ }});
657
+ }}
658
  </script>
659
  <button
660
  onclick="copyToClipboard()"
661
+ style="background-color:{theme['primary']}; color:white; border:none; padding:8px 16px; border-radius:4px; cursor:pointer;"
662
  >
663
  📋 クリップボードにコピー
664
  </button>
665
  <span id="copy-status" style="margin-left:10px; color:green;"></span>
666
  """
667
  st.markdown(js_code, unsafe_allow_html=True)
668
+
669
  st.caption("MidJourney/nijiJourneyにこのプロンプトを貼り付けて使用してください")
670
+
671
  # 使用したモデルの表示を追加
672
  st.caption(f"使用モデル: **{model}**")
673
+
674
  if explanation:
675
  st.markdown("### プロンプト解説")
676
  st.markdown(explanation)
677
 
678
  # フッター
679
  st.markdown("---")
680
+ st.markdown("© 2025 AI Art Prompt Generator - Powered by Groq & Hugging Face")