update app - [cleaned]
Browse files
app.py
CHANGED
|
@@ -169,8 +169,9 @@ footer{display:none!important}
|
|
| 169 |
width:36px;height:36px;
|
| 170 |
background:linear-gradient(135deg,#FF4500,#FF6633,#FF8C66);
|
| 171 |
border-radius:10px;display:flex;align-items:center;justify-content:center;
|
| 172 |
-
|
| 173 |
}
|
|
|
|
| 174 |
.app-title{
|
| 175 |
font-size:18px;font-weight:700;
|
| 176 |
background:linear-gradient(135deg,#e4e4e7,#a1a1aa);
|
|
@@ -208,13 +209,30 @@ footer{display:none!important}
|
|
| 208 |
background:rgba(255,69,0,.25);color:#ffffff!important;
|
| 209 |
-webkit-text-fill-color:#ffffff!important;border-color:rgba(255,69,0,.45);
|
| 210 |
}
|
| 211 |
-
.modern-tb-btn .tb-icon{font-size:15px;line-height:1;color:#ffffff!important;-webkit-text-fill-color:#ffffff!important}
|
| 212 |
.modern-tb-btn .tb-label{font-size:13px;color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;font-weight:600}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
.tb-info{
|
| 214 |
font-family:'JetBrains Mono',monospace;font-size:12px;
|
| 215 |
color:#71717a;padding:0 8px;display:flex;align-items:center;
|
| 216 |
}
|
| 217 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 218 |
/* ── Main Layout ── */
|
| 219 |
.app-main-row{display:flex;gap:0;flex:1;overflow:hidden}
|
| 220 |
.app-main-left{
|
|
@@ -321,6 +339,49 @@ footer{display:none!important}
|
|
| 321 |
color:#FF6633;transform:translateY(-1px);
|
| 322 |
}
|
| 323 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 324 |
/* ── Right Panel Cards ── */
|
| 325 |
.panel-card{border-bottom:1px solid #27272a}
|
| 326 |
.panel-card-title{
|
|
@@ -337,8 +398,46 @@ footer{display:none!important}
|
|
| 337 |
}
|
| 338 |
.modern-textarea:focus{border-color:#FF4500;box-shadow:0 0 0 3px rgba(255,69,0,.15)}
|
| 339 |
.modern-textarea::placeholder{color:#3f3f46}
|
| 340 |
-
|
| 341 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 342 |
.btn-run{
|
| 343 |
display:flex;align-items:center;justify-content:center;gap:8px;
|
| 344 |
width:100%;background:linear-gradient(135deg,#FF4500,#E63E00);
|
|
@@ -360,14 +459,8 @@ footer{display:none!important}
|
|
| 360 |
.btn-run:focus{color:#ffffff!important;-webkit-text-fill-color:#ffffff!important}
|
| 361 |
.btn-run svg{width:18px;height:18px;fill:#ffffff!important;color:#ffffff!important}
|
| 362 |
.btn-run svg path{fill:#ffffff!important;color:#ffffff!important}
|
| 363 |
-
.btn-run span,
|
| 364 |
-
|
| 365 |
-
#run-btn-label{color:#ffffff!important;-webkit-text-fill-color:#ffffff!important}
|
| 366 |
-
|
| 367 |
-
/* Force white on run button — every selector/theme */
|
| 368 |
-
#custom-run-btn,#custom-run-btn *,#custom-run-btn span,
|
| 369 |
-
#custom-run-btn svg,#custom-run-btn svg *,#custom-run-btn svg path,
|
| 370 |
-
#custom-run-btn #run-btn-label,.btn-run *{
|
| 371 |
color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;fill:#ffffff!important;
|
| 372 |
}
|
| 373 |
body:not(.dark) .btn-run,body:not(.dark) .btn-run *,body:not(.dark) #custom-run-btn,
|
|
@@ -383,17 +476,6 @@ body:not(.dark) #custom-run-btn *,body:not(.dark) #run-btn-label{
|
|
| 383 |
color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;fill:#ffffff!important;
|
| 384 |
}
|
| 385 |
|
| 386 |
-
/* ── Toolbar btn white in all themes ── */
|
| 387 |
-
body:not(.dark) .modern-tb-btn,body:not(.dark) .modern-tb-btn *{
|
| 388 |
-
color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;
|
| 389 |
-
}
|
| 390 |
-
.dark .modern-tb-btn,.dark .modern-tb-btn *{
|
| 391 |
-
color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;
|
| 392 |
-
}
|
| 393 |
-
.gradio-container .modern-tb-btn,.gradio-container .modern-tb-btn *{
|
| 394 |
-
color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;
|
| 395 |
-
}
|
| 396 |
-
|
| 397 |
/* ── Output Frames ── */
|
| 398 |
.output-frame{
|
| 399 |
border-bottom:1px solid #27272a;display:flex;flex-direction:column;position:relative;
|
|
@@ -412,7 +494,6 @@ body:not(.dark) .modern-tb-btn,body:not(.dark) .modern-tb-btn *{
|
|
| 412 |
}
|
| 413 |
.output-frame .out-body img{max-width:100%;max-height:460px;image-rendering:auto}
|
| 414 |
.output-frame .out-placeholder{color:#3f3f46;font-size:13px;text-align:center;padding:20px}
|
| 415 |
-
|
| 416 |
.out-download-btn{
|
| 417 |
display:none;align-items:center;justify-content:center;
|
| 418 |
background:rgba(255,69,0,.1);border:1px solid rgba(255,69,0,.2);
|
|
@@ -501,7 +582,6 @@ body:not(.dark) .modern-tb-btn,body:not(.dark) .modern-tb-btn *{
|
|
| 501 |
opacity:0.01;pointer-events:none;overflow:hidden;
|
| 502 |
}
|
| 503 |
|
| 504 |
-
/* ── Experimental Note ── */
|
| 505 |
.exp-note{
|
| 506 |
padding:10px 20px;font-size:12px;color:#52525b;border-top:1px solid #27272a;
|
| 507 |
text-align:center;
|
|
@@ -509,7 +589,6 @@ body:not(.dark) .modern-tb-btn,body:not(.dark) .modern-tb-btn *{
|
|
| 509 |
.exp-note a{color:#FF6633;text-decoration:none}
|
| 510 |
.exp-note a:hover{text-decoration:underline}
|
| 511 |
|
| 512 |
-
/* ── Dark mode extras ── */
|
| 513 |
.dark .app-shell{background:#18181b}
|
| 514 |
.dark .upload-prompt-modern{background:transparent}
|
| 515 |
.dark .panel-card{background:#18181b}
|
|
@@ -519,13 +598,11 @@ body:not(.dark) .modern-tb-btn,body:not(.dark) .modern-tb-btn *{
|
|
| 519 |
.dark .out-download-btn{color:#FF8C66!important}
|
| 520 |
.dark .out-download-btn:hover{color:#ffffff!important}
|
| 521 |
|
| 522 |
-
/* ── Scrollbar ── */
|
| 523 |
::-webkit-scrollbar{width:8px;height:8px}
|
| 524 |
::-webkit-scrollbar-track{background:#09090b}
|
| 525 |
::-webkit-scrollbar-thumb{background:#27272a;border-radius:4px}
|
| 526 |
::-webkit-scrollbar-thumb:hover{background:#3f3f46}
|
| 527 |
|
| 528 |
-
/* ── Responsive ── */
|
| 529 |
@media(max-width:840px){
|
| 530 |
.app-main-row{flex-direction:column}
|
| 531 |
.app-main-right{width:100%}
|
|
@@ -561,6 +638,37 @@ function init() {
|
|
| 561 |
let images = [];
|
| 562 |
window.__uploadedImages = images;
|
| 563 |
let selectedIdx = -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 564 |
|
| 565 |
function setGradioValue(containerId, value) {
|
| 566 |
const container = document.getElementById(containerId);
|
|
@@ -600,6 +708,7 @@ function init() {
|
|
| 600 |
renderGallery();
|
| 601 |
syncImagesToGradio();
|
| 602 |
}
|
|
|
|
| 603 |
|
| 604 |
function removeImage(idx) {
|
| 605 |
images.splice(idx, 1);
|
|
@@ -616,6 +725,7 @@ function init() {
|
|
| 616 |
renderGallery();
|
| 617 |
syncImagesToGradio();
|
| 618 |
}
|
|
|
|
| 619 |
|
| 620 |
function selectImage(idx) {
|
| 621 |
selectedIdx = (selectedIdx === idx) ? -1 : idx;
|
|
@@ -698,6 +808,91 @@ function init() {
|
|
| 698 |
if (promptInput) { promptInput.value = text; syncPromptToGradio(); }
|
| 699 |
};
|
| 700 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 701 |
function syncSlider(customId, gradioId) {
|
| 702 |
const slider = document.getElementById(customId);
|
| 703 |
const valSpan = document.getElementById(customId + '-val');
|
|
@@ -745,7 +940,28 @@ function init() {
|
|
| 745 |
window.__showLoader = showLoader;
|
| 746 |
window.__hideLoader = hideLoader;
|
| 747 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 748 |
window.__clickGradioRunBtn = function() {
|
|
|
|
| 749 |
syncPromptToGradio();
|
| 750 |
syncImagesToGradio();
|
| 751 |
showLoader();
|
|
@@ -834,6 +1050,14 @@ watchSeed();
|
|
| 834 |
|
| 835 |
DOWNLOAD_SVG = '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 16l-5-5h3V4h4v7h3l-5 5z"/><path d="M20 18H4v2h16v-2z"/></svg>'
|
| 836 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 837 |
with gr.Blocks() as demo:
|
| 838 |
|
| 839 |
hidden_images_b64 = gr.Textbox(
|
|
@@ -868,32 +1092,32 @@ with gr.Blocks() as demo:
|
|
| 868 |
gr.HTML(f"""
|
| 869 |
<div class="app-shell">
|
| 870 |
|
| 871 |
-
<!--
|
| 872 |
<div class="app-header">
|
| 873 |
<div class="app-header-left">
|
| 874 |
-
<div class="app-logo">
|
| 875 |
<span class="app-title">FireRed-Image-Edit</span>
|
| 876 |
<span class="app-badge">v1.1</span>
|
| 877 |
<span class="app-badge fast">4-Step Fast</span>
|
| 878 |
</div>
|
| 879 |
</div>
|
| 880 |
|
| 881 |
-
<!--
|
| 882 |
<div class="app-toolbar">
|
| 883 |
<button id="tb-upload" class="modern-tb-btn" title="Upload images">
|
| 884 |
-
<span class="tb-
|
| 885 |
</button>
|
| 886 |
<button id="tb-remove" class="modern-tb-btn" title="Remove selected image">
|
| 887 |
-
<span class="tb-
|
| 888 |
</button>
|
| 889 |
<button id="tb-clear" class="modern-tb-btn" title="Clear all images">
|
| 890 |
-
<span class="tb-
|
| 891 |
</button>
|
| 892 |
<div class="tb-sep"></div>
|
| 893 |
<span id="tb-image-count" class="tb-info">No images</span>
|
| 894 |
</div>
|
| 895 |
|
| 896 |
-
<!--
|
| 897 |
<div class="app-main-row">
|
| 898 |
|
| 899 |
<!-- Left: Gallery -->
|
|
@@ -924,16 +1148,95 @@ with gr.Blocks() as demo:
|
|
| 924 |
<div class="suggestions-section">
|
| 925 |
<div class="suggestions-title">Quick Prompts</div>
|
| 926 |
<div class="suggestions-wrap">
|
| 927 |
-
<button class="suggestion-chip" onclick="window.__setPrompt('Transform the image into a dotted cartoon style.')">
|
| 928 |
-
<button class="suggestion-chip" onclick="window.__setPrompt('Convert it to black and white.')">
|
| 929 |
-
<button class="suggestion-chip" onclick="window.__setPrompt('Add cinematic lighting with warm orange tones and film grain.')">
|
| 930 |
-
<button class="suggestion-chip" onclick="window.__setPrompt('Transform into anime style illustration.')">
|
| 931 |
-
<button class="suggestion-chip" onclick="window.__setPrompt('Apply oil painting effect with visible brush strokes.')">
|
| 932 |
-
<button class="suggestion-chip" onclick="window.__setPrompt('Enhance and upscale with more detail and clarity.')">
|
| 933 |
-
<button class="suggestion-chip" onclick="window.__setPrompt('Make it look like a watercolor painting with soft edges.')">
|
| 934 |
-
<button class="suggestion-chip" onclick="window.__setPrompt('Add dramatic sunset sky and warm lighting.')">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 935 |
</div>
|
| 936 |
</div>
|
|
|
|
| 937 |
</div>
|
| 938 |
|
| 939 |
<!-- Right: Controls & Output -->
|
|
@@ -964,7 +1267,7 @@ with gr.Blocks() as demo:
|
|
| 964 |
<div class="out-body" id="output-image-container">
|
| 965 |
<div class="modern-loader" id="output-loader">
|
| 966 |
<div class="loader-spinner"></div>
|
| 967 |
-
<div class="loader-text">Processing image
|
| 968 |
<div class="loader-bar-track"><div class="loader-bar-fill"></div></div>
|
| 969 |
</div>
|
| 970 |
<div class="out-placeholder" id="output-placeholder">Result will appear here</div>
|
|
@@ -999,13 +1302,13 @@ with gr.Blocks() as demo:
|
|
| 999 |
</div>
|
| 1000 |
</div>
|
| 1001 |
|
| 1002 |
-
<!--
|
| 1003 |
<div class="exp-note">
|
| 1004 |
Experimental Space for <a href="https://huggingface.co/FireRedTeam/FireRed-Image-Edit-1.1" target="_blank">FireRed-Image-Edit-1.1</a>
|
| 1005 |
-
|
| 1006 |
</div>
|
| 1007 |
|
| 1008 |
-
<!--
|
| 1009 |
<div class="app-statusbar">
|
| 1010 |
<div class="sb-section" id="sb-image-count">No images uploaded</div>
|
| 1011 |
<div class="sb-section sb-fixed">Ready</div>
|
|
@@ -1035,5 +1338,9 @@ with gr.Blocks() as demo:
|
|
| 1035 |
|
| 1036 |
if __name__ == "__main__":
|
| 1037 |
demo.queue(max_size=30).launch(
|
| 1038 |
-
css=css,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1039 |
)
|
|
|
|
| 169 |
width:36px;height:36px;
|
| 170 |
background:linear-gradient(135deg,#FF4500,#FF6633,#FF8C66);
|
| 171 |
border-radius:10px;display:flex;align-items:center;justify-content:center;
|
| 172 |
+
box-shadow:0 4px 12px rgba(255,69,0,.35);
|
| 173 |
}
|
| 174 |
+
.app-logo svg{width:20px;height:20px;fill:#fff;flex-shrink:0}
|
| 175 |
.app-title{
|
| 176 |
font-size:18px;font-weight:700;
|
| 177 |
background:linear-gradient(135deg,#e4e4e7,#a1a1aa);
|
|
|
|
| 209 |
background:rgba(255,69,0,.25);color:#ffffff!important;
|
| 210 |
-webkit-text-fill-color:#ffffff!important;border-color:rgba(255,69,0,.45);
|
| 211 |
}
|
|
|
|
| 212 |
.modern-tb-btn .tb-label{font-size:13px;color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;font-weight:600}
|
| 213 |
+
.modern-tb-btn .tb-svg{
|
| 214 |
+
width:15px;height:15px;flex-shrink:0;
|
| 215 |
+
stroke:#ffffff!important;color:#ffffff!important;
|
| 216 |
+
}
|
| 217 |
.tb-info{
|
| 218 |
font-family:'JetBrains Mono',monospace;font-size:12px;
|
| 219 |
color:#71717a;padding:0 8px;display:flex;align-items:center;
|
| 220 |
}
|
| 221 |
|
| 222 |
+
/* Force toolbar white in all themes */
|
| 223 |
+
body:not(.dark) .modern-tb-btn,body:not(.dark) .modern-tb-btn *{
|
| 224 |
+
color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;
|
| 225 |
+
}
|
| 226 |
+
body:not(.dark) .modern-tb-btn .tb-svg{stroke:#ffffff!important}
|
| 227 |
+
.dark .modern-tb-btn,.dark .modern-tb-btn *{
|
| 228 |
+
color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;
|
| 229 |
+
}
|
| 230 |
+
.dark .modern-tb-btn .tb-svg{stroke:#ffffff!important}
|
| 231 |
+
.gradio-container .modern-tb-btn,.gradio-container .modern-tb-btn *{
|
| 232 |
+
color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;
|
| 233 |
+
}
|
| 234 |
+
.gradio-container .modern-tb-btn .tb-svg{stroke:#ffffff!important}
|
| 235 |
+
|
| 236 |
/* ── Main Layout ── */
|
| 237 |
.app-main-row{display:flex;gap:0;flex:1;overflow:hidden}
|
| 238 |
.app-main-left{
|
|
|
|
| 339 |
color:#FF6633;transform:translateY(-1px);
|
| 340 |
}
|
| 341 |
|
| 342 |
+
/* ── Quick Examples ── */
|
| 343 |
+
.examples-section{border-top:1px solid #27272a;padding:12px 16px}
|
| 344 |
+
.examples-title{
|
| 345 |
+
font-size:12px;font-weight:600;color:#71717a;text-transform:uppercase;
|
| 346 |
+
letter-spacing:.8px;margin-bottom:10px;
|
| 347 |
+
}
|
| 348 |
+
.examples-scroll{
|
| 349 |
+
display:flex;gap:10px;overflow-x:auto;padding-bottom:8px;
|
| 350 |
+
}
|
| 351 |
+
.examples-scroll::-webkit-scrollbar{height:6px}
|
| 352 |
+
.examples-scroll::-webkit-scrollbar-track{background:#09090b;border-radius:3px}
|
| 353 |
+
.examples-scroll::-webkit-scrollbar-thumb{background:#27272a;border-radius:3px}
|
| 354 |
+
.examples-scroll::-webkit-scrollbar-thumb:hover{background:#3f3f46}
|
| 355 |
+
.example-card{
|
| 356 |
+
flex-shrink:0;width:210px;background:#09090b;border:1px solid #27272a;
|
| 357 |
+
border-radius:10px;overflow:hidden;cursor:pointer;transition:all .2s ease;
|
| 358 |
+
}
|
| 359 |
+
.example-card:hover{
|
| 360 |
+
border-color:#FF4500;transform:translateY(-2px);
|
| 361 |
+
box-shadow:0 4px 12px rgba(255,69,0,.15);
|
| 362 |
+
}
|
| 363 |
+
.example-card.loading{opacity:.6;pointer-events:none}
|
| 364 |
+
.example-thumbs{display:flex;height:110px;overflow:hidden;background:#18181b}
|
| 365 |
+
.example-thumbs img{
|
| 366 |
+
flex:1;object-fit:cover;min-width:0;
|
| 367 |
+
border-bottom:1px solid #27272a;
|
| 368 |
+
}
|
| 369 |
+
.example-thumb-placeholder{
|
| 370 |
+
flex:1;display:flex;align-items:center;justify-content:center;
|
| 371 |
+
background:#18181b;color:#3f3f46;font-size:11px;min-width:0;
|
| 372 |
+
}
|
| 373 |
+
.example-meta{padding:6px 10px;display:flex;align-items:center;gap:6px}
|
| 374 |
+
.example-badge{
|
| 375 |
+
display:inline-flex;padding:2px 7px;
|
| 376 |
+
background:rgba(255,69,0,.1);border-radius:4px;
|
| 377 |
+
font-size:10px;font-weight:600;color:#FF6633;
|
| 378 |
+
font-family:'JetBrains Mono',monospace;white-space:nowrap;
|
| 379 |
+
}
|
| 380 |
+
.example-prompt-text{
|
| 381 |
+
padding:0 10px 8px;font-size:11px;color:#a1a1aa;line-height:1.4;
|
| 382 |
+
display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
/* ── Right Panel Cards ── */
|
| 386 |
.panel-card{border-bottom:1px solid #27272a}
|
| 387 |
.panel-card-title{
|
|
|
|
| 398 |
}
|
| 399 |
.modern-textarea:focus{border-color:#FF4500;box-shadow:0 0 0 3px rgba(255,69,0,.15)}
|
| 400 |
.modern-textarea::placeholder{color:#3f3f46}
|
| 401 |
+
.modern-textarea.error-flash{
|
| 402 |
+
border-color:#ef4444!important;
|
| 403 |
+
box-shadow:0 0 0 3px rgba(239,68,68,.2)!important;
|
| 404 |
+
animation:shake .4s ease;
|
| 405 |
+
}
|
| 406 |
+
@keyframes shake{
|
| 407 |
+
0%,100%{transform:translateX(0)}
|
| 408 |
+
20%,60%{transform:translateX(-4px)}
|
| 409 |
+
40%,80%{transform:translateX(4px)}
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
/* ── Toast ── */
|
| 413 |
+
.toast-notification{
|
| 414 |
+
position:fixed;top:24px;left:50%;transform:translateX(-50%) translateY(-120%);
|
| 415 |
+
z-index:9999;padding:10px 24px;border-radius:10px;
|
| 416 |
+
font-family:'Inter',sans-serif;font-size:14px;font-weight:600;
|
| 417 |
+
display:flex;align-items:center;gap:8px;
|
| 418 |
+
box-shadow:0 8px 24px rgba(0,0,0,.5);
|
| 419 |
+
transition:transform .35s cubic-bezier(.34,1.56,.64,1),opacity .35s ease;
|
| 420 |
+
opacity:0;pointer-events:none;
|
| 421 |
+
}
|
| 422 |
+
.toast-notification.visible{
|
| 423 |
+
transform:translateX(-50%) translateY(0);opacity:1;pointer-events:auto;
|
| 424 |
+
}
|
| 425 |
+
.toast-notification.error{
|
| 426 |
+
background:linear-gradient(135deg,#dc2626,#b91c1c);
|
| 427 |
+
color:#fff;border:1px solid rgba(255,255,255,.15);
|
| 428 |
+
}
|
| 429 |
+
.toast-notification.warning{
|
| 430 |
+
background:linear-gradient(135deg,#d97706,#b45309);
|
| 431 |
+
color:#fff;border:1px solid rgba(255,255,255,.15);
|
| 432 |
+
}
|
| 433 |
+
.toast-notification.info{
|
| 434 |
+
background:linear-gradient(135deg,#2563eb,#1d4ed8);
|
| 435 |
+
color:#fff;border:1px solid rgba(255,255,255,.15);
|
| 436 |
+
}
|
| 437 |
+
.toast-notification .toast-icon{font-size:16px;line-height:1}
|
| 438 |
+
.toast-notification .toast-text{line-height:1.3}
|
| 439 |
+
|
| 440 |
+
/* ── Primary Button ── */
|
| 441 |
.btn-run{
|
| 442 |
display:flex;align-items:center;justify-content:center;gap:8px;
|
| 443 |
width:100%;background:linear-gradient(135deg,#FF4500,#E63E00);
|
|
|
|
| 459 |
.btn-run:focus{color:#ffffff!important;-webkit-text-fill-color:#ffffff!important}
|
| 460 |
.btn-run svg{width:18px;height:18px;fill:#ffffff!important;color:#ffffff!important}
|
| 461 |
.btn-run svg path{fill:#ffffff!important;color:#ffffff!important}
|
| 462 |
+
.btn-run span,#run-btn-label{color:#ffffff!important;-webkit-text-fill-color:#ffffff!important}
|
| 463 |
+
#custom-run-btn,#custom-run-btn *,.btn-run *{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 464 |
color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;fill:#ffffff!important;
|
| 465 |
}
|
| 466 |
body:not(.dark) .btn-run,body:not(.dark) .btn-run *,body:not(.dark) #custom-run-btn,
|
|
|
|
| 476 |
color:#ffffff!important;-webkit-text-fill-color:#ffffff!important;fill:#ffffff!important;
|
| 477 |
}
|
| 478 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 479 |
/* ── Output Frames ── */
|
| 480 |
.output-frame{
|
| 481 |
border-bottom:1px solid #27272a;display:flex;flex-direction:column;position:relative;
|
|
|
|
| 494 |
}
|
| 495 |
.output-frame .out-body img{max-width:100%;max-height:460px;image-rendering:auto}
|
| 496 |
.output-frame .out-placeholder{color:#3f3f46;font-size:13px;text-align:center;padding:20px}
|
|
|
|
| 497 |
.out-download-btn{
|
| 498 |
display:none;align-items:center;justify-content:center;
|
| 499 |
background:rgba(255,69,0,.1);border:1px solid rgba(255,69,0,.2);
|
|
|
|
| 582 |
opacity:0.01;pointer-events:none;overflow:hidden;
|
| 583 |
}
|
| 584 |
|
|
|
|
| 585 |
.exp-note{
|
| 586 |
padding:10px 20px;font-size:12px;color:#52525b;border-top:1px solid #27272a;
|
| 587 |
text-align:center;
|
|
|
|
| 589 |
.exp-note a{color:#FF6633;text-decoration:none}
|
| 590 |
.exp-note a:hover{text-decoration:underline}
|
| 591 |
|
|
|
|
| 592 |
.dark .app-shell{background:#18181b}
|
| 593 |
.dark .upload-prompt-modern{background:transparent}
|
| 594 |
.dark .panel-card{background:#18181b}
|
|
|
|
| 598 |
.dark .out-download-btn{color:#FF8C66!important}
|
| 599 |
.dark .out-download-btn:hover{color:#ffffff!important}
|
| 600 |
|
|
|
|
| 601 |
::-webkit-scrollbar{width:8px;height:8px}
|
| 602 |
::-webkit-scrollbar-track{background:#09090b}
|
| 603 |
::-webkit-scrollbar-thumb{background:#27272a;border-radius:4px}
|
| 604 |
::-webkit-scrollbar-thumb:hover{background:#3f3f46}
|
| 605 |
|
|
|
|
| 606 |
@media(max-width:840px){
|
| 607 |
.app-main-row{flex-direction:column}
|
| 608 |
.app-main-right{width:100%}
|
|
|
|
| 638 |
let images = [];
|
| 639 |
window.__uploadedImages = images;
|
| 640 |
let selectedIdx = -1;
|
| 641 |
+
let toastTimer = null;
|
| 642 |
+
|
| 643 |
+
/* ── Toast ── */
|
| 644 |
+
function showToast(message, type) {
|
| 645 |
+
let toast = document.getElementById('app-toast');
|
| 646 |
+
if (!toast) {
|
| 647 |
+
toast = document.createElement('div');
|
| 648 |
+
toast.id = 'app-toast';
|
| 649 |
+
toast.className = 'toast-notification';
|
| 650 |
+
toast.innerHTML = '<span class="toast-icon"></span><span class="toast-text"></span>';
|
| 651 |
+
document.body.appendChild(toast);
|
| 652 |
+
}
|
| 653 |
+
const icon = toast.querySelector('.toast-icon');
|
| 654 |
+
const text = toast.querySelector('.toast-text');
|
| 655 |
+
toast.className = 'toast-notification ' + (type || 'error');
|
| 656 |
+
if (type === 'warning') icon.textContent = '\u26A0';
|
| 657 |
+
else if (type === 'info') icon.textContent = '\u2139';
|
| 658 |
+
else icon.textContent = '\u2717';
|
| 659 |
+
text.textContent = message;
|
| 660 |
+
if (toastTimer) clearTimeout(toastTimer);
|
| 661 |
+
void toast.offsetWidth;
|
| 662 |
+
toast.classList.add('visible');
|
| 663 |
+
toastTimer = setTimeout(() => toast.classList.remove('visible'), 3500);
|
| 664 |
+
}
|
| 665 |
+
|
| 666 |
+
function flashPromptError() {
|
| 667 |
+
if (!promptInput) return;
|
| 668 |
+
promptInput.classList.add('error-flash');
|
| 669 |
+
promptInput.focus();
|
| 670 |
+
setTimeout(() => promptInput.classList.remove('error-flash'), 800);
|
| 671 |
+
}
|
| 672 |
|
| 673 |
function setGradioValue(containerId, value) {
|
| 674 |
const container = document.getElementById(containerId);
|
|
|
|
| 708 |
renderGallery();
|
| 709 |
syncImagesToGradio();
|
| 710 |
}
|
| 711 |
+
window.__addImage = addImage;
|
| 712 |
|
| 713 |
function removeImage(idx) {
|
| 714 |
images.splice(idx, 1);
|
|
|
|
| 725 |
renderGallery();
|
| 726 |
syncImagesToGradio();
|
| 727 |
}
|
| 728 |
+
window.__clearAll = clearAll;
|
| 729 |
|
| 730 |
function selectImage(idx) {
|
| 731 |
selectedIdx = (selectedIdx === idx) ? -1 : idx;
|
|
|
|
| 808 |
if (promptInput) { promptInput.value = text; syncPromptToGradio(); }
|
| 809 |
};
|
| 810 |
|
| 811 |
+
/* ── Example Loading ── */
|
| 812 |
+
const EXAMPLES = [
|
| 813 |
+
{
|
| 814 |
+
images: ["examples/1.jpg"],
|
| 815 |
+
prompt: "cinematic polaroid with soft grain subtle vignette gentle lighting white frame handwritten photographed 'Fire-Edit' preserving realistic texture and details."
|
| 816 |
+
},
|
| 817 |
+
{
|
| 818 |
+
images: ["examples/2.jpg"],
|
| 819 |
+
prompt: "Transform the image into a dotted cartoon style."
|
| 820 |
+
},
|
| 821 |
+
{
|
| 822 |
+
images: ["examples/3.jpeg"],
|
| 823 |
+
prompt: "Convert it to black and white."
|
| 824 |
+
},
|
| 825 |
+
{
|
| 826 |
+
images: ["examples/4.jpg", "examples/5.jpg"],
|
| 827 |
+
prompt: "Replace her glasses with the new glasses from image 1."
|
| 828 |
+
},
|
| 829 |
+
{
|
| 830 |
+
images: ["examples/8.jpg", "examples/9.png"],
|
| 831 |
+
prompt: "Replace the current clothing with the clothing from the reference image 2. Keep the person's face, hairstyle, body pose, background, lighting, and camera angle unchanged. Ensure the new outfit fits naturally with realistic fabric texture, proper shadows, folds, and accurate proportions. Match the lighting, color tone, and overall style for a seamless and high-quality result."
|
| 832 |
+
},
|
| 833 |
+
{
|
| 834 |
+
images: ["examples/10.jpg", "examples/11.png"],
|
| 835 |
+
prompt: "Replace the current clothing with the clothing from the reference image 2. Keep the person's face, hairstyle, body pose, background, lighting, and camera angle unchanged. Ensure the new outfit fits naturally with realistic fabric texture, proper shadows, folds, and accurate proportions. Match the lighting, color tone, and overall style for a seamless and high-quality result."
|
| 836 |
+
}
|
| 837 |
+
];
|
| 838 |
+
|
| 839 |
+
async function fetchImageAsBase64(path) {
|
| 840 |
+
const urls = ['/file=' + path, 'file/' + path, path, './' + path];
|
| 841 |
+
for (const url of urls) {
|
| 842 |
+
try {
|
| 843 |
+
const resp = await fetch(url);
|
| 844 |
+
if (resp.ok && resp.headers.get('content-type') &&
|
| 845 |
+
resp.headers.get('content-type').startsWith('image')) {
|
| 846 |
+
const blob = await resp.blob();
|
| 847 |
+
return await new Promise((resolve) => {
|
| 848 |
+
const reader = new FileReader();
|
| 849 |
+
reader.onload = () => resolve(reader.result);
|
| 850 |
+
reader.readAsDataURL(blob);
|
| 851 |
+
});
|
| 852 |
+
}
|
| 853 |
+
} catch (e) {}
|
| 854 |
+
}
|
| 855 |
+
return null;
|
| 856 |
+
}
|
| 857 |
+
|
| 858 |
+
async function loadExample(idx) {
|
| 859 |
+
if (idx < 0 || idx >= EXAMPLES.length) return;
|
| 860 |
+
const ex = EXAMPLES[idx];
|
| 861 |
+
|
| 862 |
+
const card = document.querySelector('.example-card[data-idx="' + idx + '"]');
|
| 863 |
+
if (card) card.classList.add('loading');
|
| 864 |
+
|
| 865 |
+
showToast('Loading example...', 'info');
|
| 866 |
+
|
| 867 |
+
clearAll();
|
| 868 |
+
|
| 869 |
+
if (promptInput) { promptInput.value = ex.prompt; syncPromptToGradio(); }
|
| 870 |
+
|
| 871 |
+
for (const path of ex.images) {
|
| 872 |
+
const b64 = await fetchImageAsBase64(path);
|
| 873 |
+
if (b64) {
|
| 874 |
+
addImage(b64, path.split('/').pop());
|
| 875 |
+
} else {
|
| 876 |
+
console.warn('Could not load example image:', path);
|
| 877 |
+
}
|
| 878 |
+
}
|
| 879 |
+
|
| 880 |
+
if (card) card.classList.remove('loading');
|
| 881 |
+
|
| 882 |
+
if (images.length > 0) {
|
| 883 |
+
showToast('Example loaded — ' + images.length + ' image(s)', 'info');
|
| 884 |
+
} else {
|
| 885 |
+
showToast('Could not load example images', 'warning');
|
| 886 |
+
}
|
| 887 |
+
}
|
| 888 |
+
window.__loadExample = loadExample;
|
| 889 |
+
|
| 890 |
+
document.querySelectorAll('.example-card[data-idx]').forEach(card => {
|
| 891 |
+
card.addEventListener('click', () => {
|
| 892 |
+
loadExample(parseInt(card.getAttribute('data-idx')));
|
| 893 |
+
});
|
| 894 |
+
});
|
| 895 |
+
|
| 896 |
function syncSlider(customId, gradioId) {
|
| 897 |
const slider = document.getElementById(customId);
|
| 898 |
const valSpan = document.getElementById(customId + '-val');
|
|
|
|
| 940 |
window.__showLoader = showLoader;
|
| 941 |
window.__hideLoader = hideLoader;
|
| 942 |
|
| 943 |
+
function validateBeforeRun() {
|
| 944 |
+
const promptVal = promptInput ? promptInput.value.trim() : '';
|
| 945 |
+
const hasImages = images.length > 0;
|
| 946 |
+
if (!hasImages && !promptVal) {
|
| 947 |
+
showToast('Please upload an image and enter a prompt', 'error');
|
| 948 |
+
flashPromptError();
|
| 949 |
+
return false;
|
| 950 |
+
}
|
| 951 |
+
if (!hasImages) {
|
| 952 |
+
showToast('Please upload at least one image', 'error');
|
| 953 |
+
return false;
|
| 954 |
+
}
|
| 955 |
+
if (!promptVal) {
|
| 956 |
+
showToast('Please enter an edit prompt', 'warning');
|
| 957 |
+
flashPromptError();
|
| 958 |
+
return false;
|
| 959 |
+
}
|
| 960 |
+
return true;
|
| 961 |
+
}
|
| 962 |
+
|
| 963 |
window.__clickGradioRunBtn = function() {
|
| 964 |
+
if (!validateBeforeRun()) return;
|
| 965 |
syncPromptToGradio();
|
| 966 |
syncImagesToGradio();
|
| 967 |
showLoader();
|
|
|
|
| 1050 |
|
| 1051 |
DOWNLOAD_SVG = '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 16l-5-5h3V4h4v7h3l-5 5z"/><path d="M20 18H4v2h16v-2z"/></svg>'
|
| 1052 |
|
| 1053 |
+
UPLOAD_SVG = '<svg class="tb-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>'
|
| 1054 |
+
|
| 1055 |
+
REMOVE_SVG = '<svg class="tb-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>'
|
| 1056 |
+
|
| 1057 |
+
CLEAR_SVG = '<svg class="tb-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>'
|
| 1058 |
+
|
| 1059 |
+
FIRE_LOGO_SVG = '<svg viewBox="0 0 24 24" fill="white" xmlns="http://www.w3.org/2000/svg"><path d="M12 23c-3.6 0-8-2.69-8-7.5 0-3.5 3-6.5 4.5-8 .27-.27.75-.08.75.28v2.44c0 .42.5.63.72.28C12.28 7.5 13 3 13 1c0-.42.48-.64.8-.35C18 4.5 20 9 20 12c0 5.5-3.5 11-8 11z"/></svg>'
|
| 1060 |
+
|
| 1061 |
with gr.Blocks() as demo:
|
| 1062 |
|
| 1063 |
hidden_images_b64 = gr.Textbox(
|
|
|
|
| 1092 |
gr.HTML(f"""
|
| 1093 |
<div class="app-shell">
|
| 1094 |
|
| 1095 |
+
<!-- Header -->
|
| 1096 |
<div class="app-header">
|
| 1097 |
<div class="app-header-left">
|
| 1098 |
+
<div class="app-logo">{FIRE_LOGO_SVG}</div>
|
| 1099 |
<span class="app-title">FireRed-Image-Edit</span>
|
| 1100 |
<span class="app-badge">v1.1</span>
|
| 1101 |
<span class="app-badge fast">4-Step Fast</span>
|
| 1102 |
</div>
|
| 1103 |
</div>
|
| 1104 |
|
| 1105 |
+
<!-- Toolbar -->
|
| 1106 |
<div class="app-toolbar">
|
| 1107 |
<button id="tb-upload" class="modern-tb-btn" title="Upload images">
|
| 1108 |
+
{UPLOAD_SVG}<span class="tb-label">Upload</span>
|
| 1109 |
</button>
|
| 1110 |
<button id="tb-remove" class="modern-tb-btn" title="Remove selected image">
|
| 1111 |
+
{REMOVE_SVG}<span class="tb-label">Remove</span>
|
| 1112 |
</button>
|
| 1113 |
<button id="tb-clear" class="modern-tb-btn" title="Clear all images">
|
| 1114 |
+
{CLEAR_SVG}<span class="tb-label">Clear All</span>
|
| 1115 |
</button>
|
| 1116 |
<div class="tb-sep"></div>
|
| 1117 |
<span id="tb-image-count" class="tb-info">No images</span>
|
| 1118 |
</div>
|
| 1119 |
|
| 1120 |
+
<!-- Main -->
|
| 1121 |
<div class="app-main-row">
|
| 1122 |
|
| 1123 |
<!-- Left: Gallery -->
|
|
|
|
| 1148 |
<div class="suggestions-section">
|
| 1149 |
<div class="suggestions-title">Quick Prompts</div>
|
| 1150 |
<div class="suggestions-wrap">
|
| 1151 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Transform the image into a dotted cartoon style.')">Cartoon Style</button>
|
| 1152 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Convert it to black and white.')">Black and White</button>
|
| 1153 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Add cinematic lighting with warm orange tones and film grain.')">Cinematic</button>
|
| 1154 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Transform into anime style illustration.')">Anime Style</button>
|
| 1155 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Apply oil painting effect with visible brush strokes.')">Oil Painting</button>
|
| 1156 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Enhance and upscale with more detail and clarity.')">Enhance</button>
|
| 1157 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Make it look like a watercolor painting with soft edges.')">Watercolor</button>
|
| 1158 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Add dramatic sunset sky and warm lighting.')">Sunset Glow</button>
|
| 1159 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Convert to detailed pencil sketch with cross-hatching and shading.')">Pencil Sketch</button>
|
| 1160 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Apply pop art style with bold colors and halftone patterns.')">Pop Art</button>
|
| 1161 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Apply a vintage retro film look with faded colors and light leaks.')">Vintage Retro</button>
|
| 1162 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Add neon glow effects with vibrant colors against a dark background.')">Neon Glow</button>
|
| 1163 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Convert to pixel art style with a retro 16-bit aesthetic.')">Pixel Art</button>
|
| 1164 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Simplify into a clean minimalist illustration with flat colors.')">Minimalist</button>
|
| 1165 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Convert to low poly 3D geometric art style.')">Low Poly 3D</button>
|
| 1166 |
+
<button class="suggestion-chip" onclick="window.__setPrompt('Transform into comic book style with bold outlines and cel shading.')">Comic Book</button>
|
| 1167 |
+
</div>
|
| 1168 |
+
</div>
|
| 1169 |
+
|
| 1170 |
+
<div class="examples-section">
|
| 1171 |
+
<div class="examples-title">Quick Examples</div>
|
| 1172 |
+
<div class="examples-scroll">
|
| 1173 |
+
|
| 1174 |
+
<div class="example-card" data-idx="0">
|
| 1175 |
+
<div class="example-thumbs">
|
| 1176 |
+
<img src="/file=examples/1.jpg" onerror="this.parentElement.innerHTML='<div class=example-thumb-placeholder>Preview</div>'" alt="">
|
| 1177 |
+
</div>
|
| 1178 |
+
<div class="example-meta">
|
| 1179 |
+
<span class="example-badge">1 image</span>
|
| 1180 |
+
</div>
|
| 1181 |
+
<div class="example-prompt-text">Cinematic polaroid with soft grain, subtle vignette, gentle lighting...</div>
|
| 1182 |
+
</div>
|
| 1183 |
+
|
| 1184 |
+
<div class="example-card" data-idx="1">
|
| 1185 |
+
<div class="example-thumbs">
|
| 1186 |
+
<img src="/file=examples/2.jpg" onerror="this.parentElement.innerHTML='<div class=example-thumb-placeholder>Preview</div>'" alt="">
|
| 1187 |
+
</div>
|
| 1188 |
+
<div class="example-meta">
|
| 1189 |
+
<span class="example-badge">1 image</span>
|
| 1190 |
+
</div>
|
| 1191 |
+
<div class="example-prompt-text">Transform the image into a dotted cartoon style.</div>
|
| 1192 |
+
</div>
|
| 1193 |
+
|
| 1194 |
+
<div class="example-card" data-idx="2">
|
| 1195 |
+
<div class="example-thumbs">
|
| 1196 |
+
<img src="/file=examples/3.jpeg" onerror="this.parentElement.innerHTML='<div class=example-thumb-placeholder>Preview</div>'" alt="">
|
| 1197 |
+
</div>
|
| 1198 |
+
<div class="example-meta">
|
| 1199 |
+
<span class="example-badge">1 image</span>
|
| 1200 |
+
</div>
|
| 1201 |
+
<div class="example-prompt-text">Convert it to black and white.</div>
|
| 1202 |
+
</div>
|
| 1203 |
+
|
| 1204 |
+
<div class="example-card" data-idx="3">
|
| 1205 |
+
<div class="example-thumbs">
|
| 1206 |
+
<img src="/file=examples/4.jpg" onerror="this.parentElement.innerHTML='<div class=example-thumb-placeholder>Preview</div>'" alt="">
|
| 1207 |
+
<img src="/file=examples/5.jpg" onerror="this.parentElement.innerHTML='<div class=example-thumb-placeholder>Preview</div>'" alt="">
|
| 1208 |
+
</div>
|
| 1209 |
+
<div class="example-meta">
|
| 1210 |
+
<span class="example-badge">2 images</span>
|
| 1211 |
+
</div>
|
| 1212 |
+
<div class="example-prompt-text">Replace her glasses with the new glasses from image 1.</div>
|
| 1213 |
+
</div>
|
| 1214 |
+
|
| 1215 |
+
<div class="example-card" data-idx="4">
|
| 1216 |
+
<div class="example-thumbs">
|
| 1217 |
+
<img src="/file=examples/8.jpg" onerror="this.parentElement.innerHTML='<div class=example-thumb-placeholder>Preview</div>'" alt="">
|
| 1218 |
+
<img src="/file=examples/9.png" onerror="this.parentElement.innerHTML='<div class=example-thumb-placeholder>Preview</div>'" alt="">
|
| 1219 |
+
</div>
|
| 1220 |
+
<div class="example-meta">
|
| 1221 |
+
<span class="example-badge">2 images</span>
|
| 1222 |
+
</div>
|
| 1223 |
+
<div class="example-prompt-text">Replace clothing with reference. Keep face, pose, and background unchanged...</div>
|
| 1224 |
+
</div>
|
| 1225 |
+
|
| 1226 |
+
<div class="example-card" data-idx="5">
|
| 1227 |
+
<div class="example-thumbs">
|
| 1228 |
+
<img src="/file=examples/10.jpg" onerror="this.parentElement.innerHTML='<div class=example-thumb-placeholder>Preview</div>'" alt="">
|
| 1229 |
+
<img src="/file=examples/11.png" onerror="this.parentElement.innerHTML='<div class=example-thumb-placeholder>Preview</div>'" alt="">
|
| 1230 |
+
</div>
|
| 1231 |
+
<div class="example-meta">
|
| 1232 |
+
<span class="example-badge">2 images</span>
|
| 1233 |
+
</div>
|
| 1234 |
+
<div class="example-prompt-text">Replace clothing with reference. Keep face, pose, and background unchanged...</div>
|
| 1235 |
+
</div>
|
| 1236 |
+
|
| 1237 |
</div>
|
| 1238 |
</div>
|
| 1239 |
+
|
| 1240 |
</div>
|
| 1241 |
|
| 1242 |
<!-- Right: Controls & Output -->
|
|
|
|
| 1267 |
<div class="out-body" id="output-image-container">
|
| 1268 |
<div class="modern-loader" id="output-loader">
|
| 1269 |
<div class="loader-spinner"></div>
|
| 1270 |
+
<div class="loader-text">Processing image...</div>
|
| 1271 |
<div class="loader-bar-track"><div class="loader-bar-fill"></div></div>
|
| 1272 |
</div>
|
| 1273 |
<div class="out-placeholder" id="output-placeholder">Result will appear here</div>
|
|
|
|
| 1302 |
</div>
|
| 1303 |
</div>
|
| 1304 |
|
| 1305 |
+
<!-- Note -->
|
| 1306 |
<div class="exp-note">
|
| 1307 |
Experimental Space for <a href="https://huggingface.co/FireRedTeam/FireRed-Image-Edit-1.1" target="_blank">FireRed-Image-Edit-1.1</a>
|
| 1308 |
+
· Open on <a href="https://github.com/PRITHIVSAKTHIUR/FireRed-Image-Edit-1.0-Fast" target="_blank">GitHub</a>
|
| 1309 |
</div>
|
| 1310 |
|
| 1311 |
+
<!-- Status Bar -->
|
| 1312 |
<div class="app-statusbar">
|
| 1313 |
<div class="sb-section" id="sb-image-count">No images uploaded</div>
|
| 1314 |
<div class="sb-section sb-fixed">Ready</div>
|
|
|
|
| 1338 |
|
| 1339 |
if __name__ == "__main__":
|
| 1340 |
demo.queue(max_size=30).launch(
|
| 1341 |
+
css=css,
|
| 1342 |
+
mcp_server=True,
|
| 1343 |
+
ssr_mode=False,
|
| 1344 |
+
show_error=True,
|
| 1345 |
+
allowed_paths=["examples"],
|
| 1346 |
)
|