Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <title>Image Restoration & Colorization</title> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap'); | |
| * { | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Montserrat', sans-serif; | |
| background: radial-gradient(circle at top left, #667eea, #764ba2, #6b46c1); | |
| margin: 0; | |
| padding: 40px 20px; | |
| color: #fff; | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| background-attachment: fixed; | |
| } | |
| h1 { | |
| font-weight: 700; | |
| font-size: 3rem; | |
| margin-bottom: 0.5em; | |
| text-shadow: 0 3px 10px rgba(0,0,0,0.4); | |
| text-align: center; | |
| animation: fadeIn 1s ease-in-out; | |
| } | |
| form { | |
| background: rgba(255, 255, 255, 0.15); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid rgba(255,255,255,0.2); | |
| border-radius: 16px; | |
| padding: 35px; | |
| max-width: 500px; | |
| width: 100%; | |
| box-shadow: 0 16px 32px rgba(0,0,0,0.25); | |
| animation: slideIn 1s ease-out; | |
| } | |
| label { | |
| display: block; | |
| font-weight: 600; | |
| margin-bottom: 10px; | |
| margin-top: 20px; | |
| font-size: 1.2rem; | |
| } | |
| input[type="file"] { | |
| border: 2px dashed rgba(255,255,255,0.7); | |
| background: rgba(255,255,255,0.1); | |
| padding: 20px 14px; | |
| border-radius: 12px; | |
| width: 100%; | |
| color: #f0f0f0; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| } | |
| input[type="file"]:hover { | |
| border-color: #fff; | |
| background: rgba(255,255,255,0.15); | |
| } | |
| button { | |
| margin-top: 30px; | |
| width: 100%; | |
| padding: 16px 0; | |
| font-size: 1.3rem; | |
| font-weight: 700; | |
| color: #fff; | |
| border: none; | |
| border-radius: 30px; | |
| background: linear-gradient(90deg, #ff758c, #ff7eb3); | |
| cursor: pointer; | |
| box-shadow: 0 8px 16px rgba(255,120,150,0.6); | |
| transition: transform 0.2s ease, box-shadow 0.2s ease; | |
| } | |
| button:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 12px 24px rgba(255,150,180,0.8); | |
| } | |
| .preview { | |
| margin-top: 50px; | |
| display: flex; | |
| justify-content: center; | |
| gap: 30px; | |
| flex-wrap: wrap; | |
| max-width: 1000px; | |
| width: 100%; | |
| } | |
| .preview > div { | |
| flex: 1 1 45%; | |
| text-align: center; | |
| animation: fadeInUp 1s ease forwards; | |
| } | |
| .preview img { | |
| max-width: 100%; | |
| max-height: 400px; | |
| border-radius: 16px; | |
| box-shadow: 0 12px 28px rgba(0,0,0,0.4); | |
| border: 4px solid rgba(255, 255, 255, 0.25); | |
| object-fit: contain; | |
| background: #111; | |
| } | |
| .preview h3 { | |
| margin-bottom: 14px; | |
| font-weight: 700; | |
| font-size: 1.4rem; | |
| text-shadow: 0 2px 6px rgba(0,0,0,0.4); | |
| } | |
| .download-link { | |
| display: inline-block; | |
| margin-top: 12px; | |
| font-size: 1.2rem; | |
| color: #fff; | |
| text-decoration: none; | |
| background: rgba(255,255,255,0.25); | |
| padding: 10px 16px; | |
| border-radius: 10px; | |
| transition: background 0.3s ease, transform 0.2s ease; | |
| } | |
| .download-link:hover { | |
| background: rgba(255,255,255,0.4); | |
| transform: scale(1.05); | |
| } | |
| @media (max-width: 640px) { | |
| form { | |
| max-width: 100%; | |
| padding: 28px 22px; | |
| } | |
| .preview > div { | |
| flex-basis: 100%; | |
| } | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(-20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| @keyframes slideIn { | |
| from { opacity: 0; transform: translateY(40px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| @keyframes fadeInUp { | |
| from { opacity: 0; transform: translateY(20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>✨ Image Restoration & Colorization</h1> | |
| <form method="POST" enctype="multipart/form-data" novalidate> | |
| <label for="image">Upload Damaged Image</label> | |
| <input id="image" type="file" name="image" accept="image/*" required> | |
| <button type="submit">✨ Enhance & Colorize</button> | |
| </form> | |
| {% if original_url and enhanced_url %} | |
| <section class="preview" aria-label="Image preview section"> | |
| <div> | |
| <h3>Original Image</h3> | |
| <img src="{{ original_url }}" alt="Original uploaded image preview" loading="lazy" /> | |
| </div> | |
| <div> | |
| <h3>Enhanced Image</h3> | |
| <img src="{{ enhanced_url }}" alt="Enhanced processed image preview" loading="lazy" /> | |
| <br /> | |
| <a class="download-link" href="{{ enhanced_url }}" download> | |
| ⬇️ Download Enhanced Image | |
| </a> | |
| </div> | |
| </section> | |
| {% endif %} | |
| </body> | |
| </html> | |