cocoat commited on
Commit
eafdc3d
·
verified ·
1 Parent(s): 9f524f5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -115
app.py CHANGED
@@ -38,8 +38,8 @@ dpm_scheduler = DPMSolverMultistepScheduler.from_config(
38
  )
39
  pipe.scheduler = euler_scheduler
40
 
41
- # 生成履歴を (PIL.Image, キャプションテキスト) タプルで保持
42
- history = []
43
 
44
  # HTMLテーブル生成ヘルパー
45
  def make_html_table(caption):
@@ -63,16 +63,13 @@ def infer(
63
  if rand:
64
  seed = random.randint(0, MAX_SEED)
65
  generator = torch.Generator(device=device).manual_seed(seed)
66
-
67
  pipe.scheduler = (
68
  euler_scheduler if scheduler_type == "Euler Ancestral" else dpm_scheduler
69
  )
70
  pipe.scheduler.set_timesteps(steps)
71
-
72
  def _callback(pipeline, step_idx, timestep, callback_kwargs):
73
- progress(step_idx / steps, desc=f"Step {step_idx}/{steps}")
74
  return callback_kwargs
75
-
76
  output = pipe(
77
  prompt=prompt,
78
  negative_prompt=neg or None,
@@ -84,7 +81,6 @@ def infer(
84
  callback_on_step_end=_callback
85
  )
86
  img = output.images[0]
87
-
88
  caption_text = (
89
  f"Prompt: {prompt}\n"
90
  f"Negative: {neg or 'None'}\n"
@@ -94,127 +90,64 @@ def infer(
94
  f"Steps: {steps}\n"
95
  f"Scheduler: {scheduler_type}"
96
  )
97
-
98
  history.insert(0, (img, caption_text))
99
  progress(1.0, desc="Done!")
100
-
101
- gallery_items = [
102
- (item[0], make_html_table(item[1]))
103
- for item in history
104
- ]
105
  return img, gallery_items
106
 
 
107
  def main():
108
  with gr.Blocks() as demo:
109
- # --- 最上部にカスタム CSS & JS をまとめて注入 ---
110
- demo.append(gr.HTML("""
111
  <style>
112
- /* 元スピナー/ローディング画面を完全に隠す */
113
- .loading-screen,
114
- .gradio-container > .loading,
115
- .gradio-container .loading {
116
- display: none !important;
117
- }
118
-
119
- /* カスタムローダー */
120
- #custom-loader {
121
- display: none;
122
- align-items: center;
123
- justify-content: center;
124
- font-weight: bold;
125
- margin: 12px 0;
126
- }
127
- body.gradio-running #custom-loader {
128
- display: flex !important;
129
- }
130
-
131
- /* 文字1文字ずつフェード */
132
- @keyframes fadeLetter {
133
- 0%,100% { opacity: 1; }
134
- 50% { opacity: 0.2; }
135
- }
136
- #custom-loader span {
137
- display: inline-block;
138
- animation: fadeLetter 1s ease-in-out infinite;
139
- }
140
-
141
- /* モーダルオーバーレイ */
142
- #modal-overlay {
143
- display: none; position: fixed; top:0; left:0;
144
- width:100vw; height:100vh;
145
- background: rgba(0,0,0,0.6);
146
- align-items: center; justify-content: center;
147
- z-index: 9999;
148
- }
149
- #modal-content {
150
- background: white; border-radius: 12px; padding: 16px;
151
- max-width: 80vw; max-height: 80vh;
152
- overflow: auto; position: relative;
153
- }
154
- #modal-close {
155
- position: absolute; top:8px; right:8px;
156
- background: #c48f61; border: none; color:white;
157
- font-size:18px; width:32px; height:32px;
158
- border-radius:50%; cursor: pointer;
159
- }
160
- #modal-img {
161
- max-width: 100%; max-height: 60vh;
162
- display: block; margin: 0 auto;
163
- }
164
- #modal-caption {
165
- margin-top: 12px;
166
- }
167
  </style>
168
 
169
- <!-- モーダルの HTML -->
170
- <div id="modal-overlay">
171
- <div id="modal-content">
172
- <button id="modal-close">&times;</button>
173
- <img id="modal-img" src="" alt="expanded"/>
174
- <div id="modal-caption"></div>
175
- </div>
176
- </div>
177
 
178
  <script>
179
- // ギャラリーのサムネイルをクリックしたらモーダルを開く
180
  document.addEventListener('click', e => {
181
  const thumb = e.target.closest('.gr-gallery img');
182
- if (thumb) {
183
  document.getElementById('modal-img').src = thumb.src;
184
- const cap = thumb.closest('figure').querySelector('figcaption')?.innerHTML || '';
185
  document.getElementById('modal-caption').innerHTML = cap;
186
  document.getElementById('modal-overlay').style.display = 'flex';
187
  }
188
- // 閉じる
189
- if (e.target.id === 'modal-close' || e.target.id === 'modal-overlay') {
190
  document.getElementById('modal-overlay').style.display = 'none';
191
  }
192
  });
193
  </script>
194
- """))
195
 
196
- # UI コンテナ
197
  with gr.Column(elem_id="col-container"):
198
  gr.Markdown("## SDXL Base – cocoamixXL3 Demo")
199
  gr.Markdown("[Link: Civitai](https://civitai.com/models/1553716?modelVersionId=1855218)")
200
 
201
- # カスタムローディング要素
202
  gr.HTML(
203
- '<div id="custom-loader">'
204
- + ''.join(
205
- f'<span style="animation-delay:{i*0.1:.1f}s">{c}</span>'
206
- for i, c in enumerate("in progress")
207
- )
208
- + '<img src="/icon.png" alt="icon" style="width:32px;height:32px;border-radius:50%;margin-left:8px;"/>'
209
- + '</div>'
210
  )
211
 
212
- # フォーム
213
  with gr.Row():
214
- prompt = gr.Textbox(lines=1, placeholder="Prompt…",
215
- value="1girl, cocoart, masterpiece, anime,")
216
- neg = gr.Textbox(lines=1, placeholder="Negative prompt",
217
- value="low quality, worst quality, bad shadow, lowres, error,…")
218
  with gr.Row():
219
  seed_sl = gr.Slider(0, MAX_SEED, step=1, value=0, label="Seed")
220
  rand = gr.Checkbox(True, label="Randomize seed")
@@ -225,27 +158,13 @@ document.addEventListener('click', e => {
225
  cfg = gr.Slider(1.0, 30.0, step=0.1, value=7.5, label="CFG Scale")
226
  steps = gr.Slider(1, 50, step=1, value=12, label="Steps")
227
  with gr.Row():
228
- scheduler_type = gr.Radio(
229
- choices=["Euler Ancestral", "DPM++ 2M SDE"],
230
- value="Euler Ancestral",
231
- label="Scheduler"
232
- )
233
  run = gr.Button("Generate")
234
 
235
- # 出力
236
  img_out = gr.Image()
237
- history_gallery = gr.Gallery(
238
- label="生成履歴", columns=4, height=280,
239
- show_label=False, show_caption=True,
240
- interactive=True, type="pil"
241
- )
242
-
243
- run.click(
244
- fn=infer,
245
- inputs=[prompt, neg, seed_sl, rand, width, height, cfg, steps, scheduler_type],
246
- outputs=[img_out, history_gallery]
247
- )
248
 
 
249
  demo.queue()
250
  demo.launch()
251
 
 
38
  )
39
  pipe.scheduler = euler_scheduler
40
 
41
+ # 生成履歴保持
42
+ dhistory = []
43
 
44
  # HTMLテーブル生成ヘルパー
45
  def make_html_table(caption):
 
63
  if rand:
64
  seed = random.randint(0, MAX_SEED)
65
  generator = torch.Generator(device=device).manual_seed(seed)
 
66
  pipe.scheduler = (
67
  euler_scheduler if scheduler_type == "Euler Ancestral" else dpm_scheduler
68
  )
69
  pipe.scheduler.set_timesteps(steps)
 
70
  def _callback(pipeline, step_idx, timestep, callback_kwargs):
71
+ progress(step_idx/steps, desc=f"Step {step_idx}/{steps}")
72
  return callback_kwargs
 
73
  output = pipe(
74
  prompt=prompt,
75
  negative_prompt=neg or None,
 
81
  callback_on_step_end=_callback
82
  )
83
  img = output.images[0]
 
84
  caption_text = (
85
  f"Prompt: {prompt}\n"
86
  f"Negative: {neg or 'None'}\n"
 
90
  f"Steps: {steps}\n"
91
  f"Scheduler: {scheduler_type}"
92
  )
 
93
  history.insert(0, (img, caption_text))
94
  progress(1.0, desc="Done!")
95
+ gallery_items = [(item[0], make_html_table(item[1])) for item in history]
 
 
 
 
96
  return img, gallery_items
97
 
98
+ # Gradio UI
99
  def main():
100
  with gr.Blocks() as demo:
101
+ # カスタム CSS/JS を直接挿入
102
+ gr.HTML(_js=None,_html="""
103
  <style>
104
+ .loading-screen, .gradio-container > .loading, .gradio-container .loading { display: none !important; }
105
+ #custom-loader { display: none; align-items: center; justify-content: center; font-weight: bold; margin: 12px 0; }
106
+ body.gradio-running #custom-loader { display: flex !important; }
107
+ @keyframes fadeLetter { 0%,100% { opacity:1; } 50% { opacity:0.2; }}
108
+ #modal-overlay { display:none; position:fixed; top:0; left:0; width:100vw; height:100vh; background:rgba(0,0,0,0.6); align-items:center; justify-content:center; z-index:9999; }
109
+ #modal-content { background:white; border-radius:12px; padding:16px; max-width:80vw; max-height:80vh; overflow:auto; position:relative; }
110
+ #modal-close { position:absolute; top:8px; right:8px; background:#c48f61; border:none; color:white; font-size:18px; width:32px; height:32px; border-radius:50%; cursor:pointer; }
111
+ #modal-img { max-width:100%; max-height:60vh; display:block; margin:0 auto; }
112
+ #modal-caption { margin-top:12px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  </style>
114
 
115
+ <div id="modal-overlay"><div id="modal-content">
116
+ <button id="modal-close">×</button>
117
+ <img id="modal-img" src="" alt="expanded"/>
118
+ <div id="modal-caption"></div>
119
+ </div></div>
 
 
 
120
 
121
  <script>
 
122
  document.addEventListener('click', e => {
123
  const thumb = e.target.closest('.gr-gallery img');
124
+ if(thumb) {
125
  document.getElementById('modal-img').src = thumb.src;
126
+ const cap = thumb.closest('figure').querySelector('figcaption')?.innerHTML||'';
127
  document.getElementById('modal-caption').innerHTML = cap;
128
  document.getElementById('modal-overlay').style.display = 'flex';
129
  }
130
+ if(e.target.id==='modal-close'||e.target.id==='modal-overlay') {
 
131
  document.getElementById('modal-overlay').style.display = 'none';
132
  }
133
  });
134
  </script>
135
+ """)
136
 
 
137
  with gr.Column(elem_id="col-container"):
138
  gr.Markdown("## SDXL Base – cocoamixXL3 Demo")
139
  gr.Markdown("[Link: Civitai](https://civitai.com/models/1553716?modelVersionId=1855218)")
140
 
 
141
  gr.HTML(
142
+ '<div id="custom-loader">' + ''.join(
143
+ f'<span style="animation:fadeLetter 1s ease-in-out infinite;animation-delay:{i*0.1:.1f}s">{c}</span>'
144
+ for i,c in enumerate("in progress")
145
+ ) + '<img src="/icon.png" style="width:32px;height:32px;border-radius:50%;margin-left:8px;"/></div>'
 
 
 
146
  )
147
 
 
148
  with gr.Row():
149
+ prompt = gr.Textbox(lines=1, placeholder="Prompt…", value="1girl, cocoart, masterpiece, anime,")
150
+ neg = gr.Textbox(lines=1, placeholder="Negative prompt", value="low quality, worst quality, ")
 
 
151
  with gr.Row():
152
  seed_sl = gr.Slider(0, MAX_SEED, step=1, value=0, label="Seed")
153
  rand = gr.Checkbox(True, label="Randomize seed")
 
158
  cfg = gr.Slider(1.0, 30.0, step=0.1, value=7.5, label="CFG Scale")
159
  steps = gr.Slider(1, 50, step=1, value=12, label="Steps")
160
  with gr.Row():
161
+ scheduler_type = gr.Radio(choices=["Euler Ancestral","DPM++ 2M SDE"], value="Euler Ancestral", label="Scheduler")
 
 
 
 
162
  run = gr.Button("Generate")
163
 
 
164
  img_out = gr.Image()
165
+ history_gallery = gr.Gallery(label="生成履歴", columns=4, height=280, show_label=False, interactive=True, type="pil")
 
 
 
 
 
 
 
 
 
 
166
 
167
+ run.click(fn=infer, inputs=[prompt, neg, seed_sl, rand, width, height, cfg, steps, scheduler_type], outputs=[img_out, history_gallery])
168
  demo.queue()
169
  demo.launch()
170