Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, UploadFile, File | |
| from fastapi.responses import HTMLResponse | |
| from PIL import Image | |
| import io | |
| import torch | |
| from transformers import BlipProcessor, BlipForConditionalGeneration | |
| app = FastAPI() | |
| # Load BLIP model & processor | |
| processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base") | |
| model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base") | |
| async def main(): | |
| return """ | |
| <html> | |
| <head> | |
| <title>Smart Image Captioning</title> | |
| <style> | |
| body { | |
| font-family: 'Segoe UI', sans-serif; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| min-height: 100vh; | |
| background-color: #f3f4f6; | |
| margin: 0; | |
| } | |
| h2 { | |
| color: #111827; | |
| margin-bottom: 1rem; | |
| } | |
| form { | |
| background: white; | |
| padding: 2rem; | |
| border-radius: 12px; | |
| box-shadow: 0 8px 24px rgba(0,0,0,0.1); | |
| } | |
| input[type="file"] { | |
| margin-bottom: 1rem; | |
| } | |
| input[type="submit"] { | |
| padding: 0.5rem 1.2rem; | |
| font-size: 1rem; | |
| background-color: #2563eb; | |
| color: white; | |
| border: none; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| } | |
| input[type="submit"]:hover { | |
| background-color: #1d4ed8; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h2>๐ง Smart Image Captioning</h2> | |
| <form action="/caption" enctype="multipart/form-data" method="post"> | |
| <input name="file" type="file" accept="image/*" required><br> | |
| <input type="submit" value="Generate Caption"> | |
| </form> | |
| </body> | |
| </html> | |
| """ | |
| async def caption(file: UploadFile = File(...)): | |
| contents = await file.read() | |
| image = Image.open(io.BytesIO(contents)).convert('RGB') | |
| # Generate caption | |
| inputs = processor(images=image, return_tensors="pt") | |
| out = model.generate(**inputs) | |
| caption = processor.decode(out[0], skip_special_tokens=True) | |
| return f""" | |
| <html> | |
| <head> | |
| <title>Caption Result</title> | |
| <style> | |
| body {{ | |
| font-family: 'Segoe UI', sans-serif; | |
| background-color: #f9fafb; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| min-height: 100vh; | |
| padding: 2rem; | |
| }} | |
| .box {{ | |
| background: white; | |
| padding: 2rem; | |
| border-radius: 12px; | |
| box-shadow: 0 8px 20px rgba(0,0,0,0.1); | |
| text-align: center; | |
| }} | |
| .caption {{ | |
| font-size: 1.25rem; | |
| color: #1f2937; | |
| margin-top: 1rem; | |
| }} | |
| a {{ | |
| display: inline-block; | |
| margin-top: 1.5rem; | |
| color: #2563eb; | |
| text-decoration: none; | |
| font-weight: bold; | |
| }} | |
| a:hover {{ | |
| text-decoration: underline; | |
| }} | |
| </style> | |
| </head> | |
| <body> | |
| <div class="box"> | |
| <h2>๐ผ๏ธ Image Caption Result</h2> | |
| <p><b>File:</b> {file.filename}</p> | |
| <p class="caption"><b>Caption:</b> {caption}</p> | |
| <a href="/">๐ Try another image</a> | |
| </div> | |
| </body> | |
| </html> | |
| """ | |