yooi commited on
Commit
2e69373
·
verified ·
1 Parent(s): d2a69c5

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +146 -48
app.py CHANGED
@@ -86,57 +86,152 @@ def do_everything(poem: str, greeting: str, style_id: str, song_style: str, dura
86
  yield understanding, brief_en, card, painting, audio, video
87
 
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  CSS = """
90
- :root { --ink: #2b2620; --vermilion: #a63a2b; --paper: #f6f1e5; --paper-deep: #efe7d4; }
91
- .gradio-container {
 
 
 
 
 
 
 
 
 
92
  background:
93
- radial-gradient(1200px 500px at 80% -10%, #fbf7ec 0%, transparent 60%),
94
- radial-gradient(900px 400px at -10% 110%, #f1e8d2 0%, transparent 55%),
95
  var(--paper) !important;
96
- font-family: "Noto Serif SC", "Source Han Serif SC", "Songti SC", serif !important;
97
  color: var(--ink);
98
  }
99
- #title-block h1 {
100
- font-size: 2.6rem; letter-spacing: 0.35rem; color: var(--ink);
101
- border-bottom: 1px solid #d8cdb4; padding-bottom: 0.6rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  }
103
- #title-block .seal {
104
- display: inline-block; background: var(--vermilion); color: #faf5eb;
105
- padding: 0.1rem 0.45rem; border-radius: 4px; margin-left: 0.6rem;
106
- font-size: 1.4rem; vertical-align: middle;
107
  }
108
- .step-card {
109
- background: rgba(255, 252, 244, 0.82) !important;
110
- border: 1px solid #ddd2b8 !important; border-radius: 14px !important;
111
- box-shadow: 0 2px 14px rgba(90, 70, 40, 0.08) !important;
112
- padding: 1rem !important; margin-top: 1rem !important;
 
 
113
  }
114
- .step-card .label-wrap span, .step-card label span { font-size: 1.05rem !important; }
115
- button.primary, .primary {
116
- background: var(--vermilion) !important; border: none !important;
117
- font-size: 1.15rem !important; letter-spacing: 0.2rem;
118
  }
119
- button.primary:hover { filter: brightness(1.08); }
120
- textarea, input[type="text"] { font-size: 1.15rem !important; line-height: 1.8 !important; }
121
- .step-number {
122
- color: var(--vermilion); font-size: 1.2rem; letter-spacing: 0.2rem; margin-bottom: 0;
 
 
123
  }
124
- footer { display: none !important; }
125
  """
126
 
127
- with gr.Blocks(title="诗成画 · Poem to Painting & Song") as demo:
128
- with gr.Column(elem_id="title-block"):
129
- gr.HTML(
130
- "<h1>诗成画 <span class='seal'></span></h1>"
131
- "<p style='font-size:1.1rem'>写一首小诗,我来替您读懂它、画出来、唱给您听,再让画活起来。"
132
- "每一步用的都是开源小模型。</p>"
133
- )
 
 
 
 
 
 
 
 
 
 
 
134
 
135
  brief_state = gr.State("")
136
  painting_state = gr.State(None)
137
 
138
- with gr.Group(elem_classes="step-card"):
139
- gr.Markdown("**· 写诗**", elem_classes="step-number")
140
  poem_box = gr.Textbox(
141
  label="您的诗", lines=4, placeholder="把您想说的写成几句小诗,长短都可以。"
142
  )
@@ -144,12 +239,16 @@ with gr.Blocks(title="诗成画 · Poem to Painting & Song") as demo:
144
  label="想送的问候(可以不填)", placeholder="例如:早安,或一句祝福的话"
145
  )
146
  with gr.Row():
147
- interpret_btn = gr.Button("读诗", variant="primary")
148
- everything_btn = gr.Button("一气呵成(读诗·作画·唱诗·入画)")
 
 
149
 
150
- with gr.Group(elem_classes="step-card"):
151
- gr.Markdown("**· 画中之意**", elem_classes="step-number")
152
- understanding_md = gr.Markdown("点「读诗」后,我会把读到的画面说给您听。")
 
 
153
  correction_box = gr.Textbox(
154
  label="如果我没读对,请告诉我", placeholder="例如:我想要更温暖的颜色"
155
  )
@@ -157,16 +256,16 @@ with gr.Blocks(title="诗成画 · Poem to Painting & Song") as demo:
157
  with gr.Accordion("给画师的英文说明(看看也无妨)", open=False):
158
  brief_md = gr.Markdown("")
159
 
160
- with gr.Group(elem_classes="step-card"):
161
- gr.Markdown("**· 作画**", elem_classes="step-number")
162
  style_radio = gr.Radio(
163
  IMAGE_STYLE_CHOICES, value=DEFAULT_IMAGE_STYLE, label="选一种画风"
164
  )
165
  paint_btn = gr.Button("作画", variant="primary")
166
  card_image = gr.Image(label="您的画卡", type="pil", interactive=False)
167
 
168
- with gr.Group(elem_classes="step-card"):
169
- gr.Markdown("**· 唱诗**", elem_classes="step-number")
170
  with gr.Row():
171
  song_radio = gr.Radio(
172
  SONG_STYLE_CHOICES, value=DEFAULT_SONG_STYLE, label="选一种曲风"
@@ -175,9 +274,8 @@ with gr.Blocks(title="诗成画 · Poem to Painting & Song") as demo:
175
  sing_btn = gr.Button("唱诗", variant="primary")
176
  song_audio = gr.Audio(label="您的诗,唱出来了", type="filepath", interactive=False)
177
 
178
- with gr.Group(elem_classes="step-card"):
179
- gr.Markdown("**· 入画**", elem_classes="step-number")
180
- gr.Markdown("让画轻轻动起来,配上您的歌,做成一段可以发给家人的小影片。")
181
  animate_btn = gr.Button("让画活起来", variant="primary")
182
  video_out = gr.Video(label="会唱歌的画", interactive=False)
183
 
@@ -220,4 +318,4 @@ with gr.Blocks(title="诗成画 · Poem to Painting & Song") as demo:
220
  )
221
 
222
  if __name__ == "__main__":
223
- demo.launch(css=CSS)
 
86
  yield understanding, brief_en, card, painting, audio, video
87
 
88
 
89
+ THEME = gr.themes.Base(
90
+ primary_hue=gr.themes.colors.red,
91
+ neutral_hue=gr.themes.colors.stone,
92
+ font=[gr.themes.GoogleFont("Noto Serif SC"), "Songti SC", "serif"],
93
+ ).set(
94
+ body_background_fill="#FDFBF7",
95
+ body_text_color="#3e3a39",
96
+ block_background_fill="#FFFEFB",
97
+ block_border_color="#E7DCCC",
98
+ block_label_text_color="#6f655d",
99
+ input_background_fill="#FCFAF4",
100
+ input_border_color="#E7DCCC",
101
+ button_primary_background_fill="#8c3a38",
102
+ button_primary_background_fill_hover="#9c4240",
103
+ button_primary_text_color="#FDF6EF",
104
+ )
105
+
106
+ # Distinctive layer the theme tokens can't express: brush-calligraphy title,
107
+ # vermilion seal-stamp step markers, chip-style radios, rice-paper atmosphere.
108
  CSS = """
109
+ @import url('https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng&family=Noto+Serif+SC:wght@400;500;700;900&display=swap');
110
+
111
+ :root{
112
+ --paper:#FDFBF7; --paper-card:#FFFEFB; --paper-input:#FCFAF4;
113
+ --ink:#3e3a39; --ink-soft:#6f655d; --ink-faint:#9a8f83;
114
+ --seal:#8c3a38; --line:#E7DCCC;
115
+ --serif:"Noto Serif SC","Songti SC","STSong",serif;
116
+ --brush:"Ma Shan Zheng",var(--serif);
117
+ }
118
+ .gradio-container, .gradio-container *{ font-family: var(--serif); }
119
+ .gradio-container{
120
  background:
121
+ radial-gradient(58rem 24rem at 90% -10%, rgba(140,58,56,.05), transparent 60%),
122
+ radial-gradient(46rem 22rem at -6% 110%, rgba(62,58,57,.045), transparent 55%),
123
  var(--paper) !important;
 
124
  color: var(--ink);
125
  }
126
+ #app-root{ max-width: 860px; margin: 0 auto; }
127
+ footer{ display:none !important; }
128
+
129
+ /* hero */
130
+ #hero{ text-align:center; padding: 2.2rem 0 1rem; }
131
+ #hero .brush{
132
+ font-family:var(--brush); font-size: clamp(3.2rem,10vw,5rem);
133
+ color:var(--ink); letter-spacing:.3rem; line-height:1; margin:0;
134
+ }
135
+ #hero .stamp{
136
+ display:inline-grid; place-items:center; width:2.5rem; height:2.5rem;
137
+ margin-left:.55rem; vertical-align:.4rem; background:var(--seal); color:#fbf3ec;
138
+ border-radius:8px; font-size:1.15rem; font-weight:700; transform:rotate(-4deg);
139
+ box-shadow:0 4px 12px -2px rgba(140,58,56,.45);
140
+ }
141
+ #hero .sub{ margin:1.05rem auto 0; max-width:34rem; color:var(--ink-soft);
142
+ font-size:1.06rem; line-height:1.8; letter-spacing:.02rem; }
143
+ #hero .rule{ width:60px; height:3px; margin:1.1rem auto 0; background:var(--seal);
144
+ opacity:.85; border-radius:2px; }
145
+
146
+ /* step cards */
147
+ .step{
148
+ background:var(--paper-card) !important; border:1px solid var(--line) !important;
149
+ border-radius:16px !important; padding:1.5rem 1.4rem 1.3rem !important;
150
+ margin:0 0 1.35rem !important;
151
+ box-shadow:0 1px 0 #fff inset, 0 14px 32px -22px rgba(62,58,57,.5) !important;
152
+ }
153
+ /* let the step-head HTML sit directly on the paper card, no Gradio block chrome.
154
+ the .styler wrapper around the HTML block carries a tan fill — clear it. */
155
+ .step .styler:has(.step-head){ background:transparent !important; border:none !important;
156
+ box-shadow:none !important; padding:0 !important; }
157
+ .step-head{ display:flex; align-items:center; gap:.8rem; margin-bottom:1rem; }
158
+ .step-seal{
159
+ flex:0 0 auto; width:2.4rem; height:2.4rem; display:grid; place-items:center;
160
+ background:var(--seal); color:#fbf3ec; border-radius:9px; font-size:1.25rem;
161
+ font-weight:700; box-shadow:0 4px 10px -3px rgba(140,58,56,.5);
162
+ }
163
+ .step-title{ font-size:1.34rem; font-weight:700; color:var(--ink); line-height:1.2; }
164
+ .step-sub{ font-size:.94rem; color:var(--ink-faint); margin-top:.1rem; }
165
+
166
+ /* inputs */
167
+ textarea, input[type="text"]{
168
+ font-size:1.16rem !important; line-height:1.9 !important; color:var(--ink) !important;
169
+ border-radius:10px !important;
170
+ }
171
+ textarea:focus, input[type="text"]:focus{
172
+ border-color:var(--seal) !important; box-shadow:0 0 0 3px rgba(140,58,56,.12) !important;
173
+ }
174
+
175
+ /* buttons */
176
+ button.primary, button.secondary{
177
+ min-height:58px !important; font-size:1.14rem !important; font-weight:700 !important;
178
+ letter-spacing:.12rem !important; border-radius:12px !important;
179
+ }
180
+ button.primary{ box-shadow:0 9px 22px -12px rgba(140,58,56,.7) !important; }
181
+ button.primary:hover{ filter:brightness(1.05); transform:translateY(-1px); }
182
+ button.secondary{
183
+ background:var(--paper-card) !important; color:var(--ink) !important;
184
+ border:1px solid var(--line) !important;
185
  }
186
+ .run-all button, .run-all.secondary{
187
+ background:linear-gradient(180deg,#4a4441,#322d2b) !important; color:#f3ece2 !important;
188
+ border:none !important; letter-spacing:.2rem !important;
 
189
  }
190
+ .run-all button:hover{ filter:brightness(1.08); }
191
+
192
+ /* radios as paper chips */
193
+ .step fieldset label, .step .wrap label{
194
+ background:var(--paper-input) !important; border:1px solid var(--line) !important;
195
+ border-radius:999px !important; padding:.5rem 1.05rem !important; cursor:pointer;
196
+ font-size:1.05rem !important; color:var(--ink) !important; transition:all .15s ease;
197
  }
198
+ .step fieldset label:has(input:checked), .step .wrap label:has(input:checked){
199
+ background:var(--seal) !important; border-color:var(--seal) !important; color:#fdf6ef !important;
 
 
200
  }
201
+
202
+ /* understanding panel */
203
+ #understanding{
204
+ background:var(--paper-input); border:1px solid var(--line);
205
+ border-left:3px solid var(--seal); border-radius:10px;
206
+ padding:1rem 1.15rem; font-size:1.12rem; line-height:1.9; color:var(--ink);
207
  }
208
+ #understanding h3{ color:var(--seal); margin-top:0; letter-spacing:.06rem; }
209
  """
210
 
211
+
212
+ def step_head(num: str, title: str, sub: str) -> str:
213
+ return (
214
+ f"<div class='step-head'><span class='step-seal'>{num}</span>"
215
+ f"<div><div class='step-title'>{title}</div>"
216
+ f"<div class='step-sub'>{sub}</div></div></div>"
217
+ )
218
+
219
+
220
+ with gr.Blocks(title="Poetic · 诗成画") as demo:
221
+ with gr.Column(elem_id="app-root"):
222
+ gr.HTML(
223
+ "<div id='hero'>"
224
+ "<h1 class='brush'>诗成画<span class='stamp'>印</span></h1>"
225
+ "<p class='sub'>写一首小诗,我替您读懂它、为它作画、把它唱出来,"
226
+ "再让画轻轻动起来——做成一张可以送给家人的画卡。<br>每一步都用开源小模型生成。</p>"
227
+ "<div class='rule'></div></div>"
228
+ )
229
 
230
  brief_state = gr.State("")
231
  painting_state = gr.State(None)
232
 
233
+ with gr.Group(elem_classes="step"):
234
+ gr.HTML(step_head("一", "写诗", "把心里的话写成几句,长短都可以"))
235
  poem_box = gr.Textbox(
236
  label="您的诗", lines=4, placeholder="把您想说的写成几句小诗,长短都可以。"
237
  )
 
239
  label="想送的问候(可以不填)", placeholder="例如:早安,或一句祝福的话"
240
  )
241
  with gr.Row():
242
+ interpret_btn = gr.Button("读诗", variant="primary", scale=1)
243
+ everything_btn = gr.Button(
244
+ "一气呵成 · 读诗 作画 唱诗 入画", scale=2, elem_classes="run-all"
245
+ )
246
 
247
+ with gr.Group(elem_classes="step"):
248
+ gr.HTML(step_head("二", "画中之意", "我把读到的画面说给您听,读错了可以纠正我"))
249
+ understanding_md = gr.Markdown(
250
+ "点「读诗」后,我会把读到的画面说给您听。", elem_id="understanding"
251
+ )
252
  correction_box = gr.Textbox(
253
  label="如果我没读对,请告诉我", placeholder="例如:我想要更温暖的颜色"
254
  )
 
256
  with gr.Accordion("给画师的英文说明(看看也无妨)", open=False):
257
  brief_md = gr.Markdown("")
258
 
259
+ with gr.Group(elem_classes="step"):
260
+ gr.HTML(step_head("三", "作画", "选一种画风,为这首诗画一幅画卡"))
261
  style_radio = gr.Radio(
262
  IMAGE_STYLE_CHOICES, value=DEFAULT_IMAGE_STYLE, label="选一种画风"
263
  )
264
  paint_btn = gr.Button("作画", variant="primary")
265
  card_image = gr.Image(label="您的画卡", type="pil", interactive=False)
266
 
267
+ with gr.Group(elem_classes="step"):
268
+ gr.HTML(step_head("四", "唱诗", "把这首诗唱成一首歌"))
269
  with gr.Row():
270
  song_radio = gr.Radio(
271
  SONG_STYLE_CHOICES, value=DEFAULT_SONG_STYLE, label="选一种曲风"
 
274
  sing_btn = gr.Button("唱诗", variant="primary")
275
  song_audio = gr.Audio(label="您的诗,唱出来了", type="filepath", interactive=False)
276
 
277
+ with gr.Group(elem_classes="step"):
278
+ gr.HTML(step_head("五", "入画", "让画轻轻动起来,配上您的歌,做成一段小影片"))
 
279
  animate_btn = gr.Button("让画活起来", variant="primary")
280
  video_out = gr.Video(label="会唱歌的画", interactive=False)
281
 
 
318
  )
319
 
320
  if __name__ == "__main__":
321
+ demo.launch(theme=THEME, css=CSS)