Spaces:
Running
Running
File size: 5,953 Bytes
8ffbf51 c73a6b4 6e2e0c5 9d344e1 7c56b7b 2e0de3d c73a6b4 c32572d c73a6b4 a93e14b c73a6b4 a93e14b 8ffbf51 c73a6b4 a93e14b c73a6b4 7c56b7b 99dbe33 6e2e0c5 c73a6b4 a93e14b c32572d c73a6b4 9d344e1 8ffbf51 c73a6b4 6e2e0c5 fc4d401 2e0de3d 6e2e0c5 fc4d401 2e0de3d fc4d401 d6030a5 fc4d401 99dbe33 d6030a5 8da2ebb e2109c6 2e0de3d 9d344e1 b229c91 99dbe33 c73a6b4 fc4d401 c73a6b4 9d344e1 2e0de3d e2109c6 9d344e1 e2109c6 9d344e1 e2109c6 9d344e1 e2109c6 9d344e1 e2109c6 9d344e1 e2109c6 9d344e1 e2109c6 2e0de3d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
import streamlit as st
import requests
import os
import base64
from PIL import Image
from io import BytesIO
# Set page title and layout
st.set_page_config(page_title="Image Caption Generator", layout="centered")
# API key from environment variable
API_KEY = os.environ.get("NEBIUS_API_KEY")
if not API_KEY:
st.error("API key not found. Please set the `NEBIUS_API_KEY` environment variable.")
# Function to call Nebius API
def generate_caption(image_base64, api_key):
api_url = "https://api.studio.nebius.ai/v1/chat/completions"
headers = {"Authorization": f"Bearer {api_key}"}
payload = {
"model": "Qwen/Qwen2-VL-72B-Instruct",
"messages": [
{
"role": "system",
"content": """You are an image to prompt converter. Your work is to observe each and every detail of the image and craft a detailed prompt under 75 words in this format: [image content/subject, description of action, state, and mood], [art form, style], [artist/photographer reference if needed], [additional settings such as camera and lens settings, lighting, colors, effects, texture, background, rendering].""",
},
{
"role": "user",
"content": [
{"type": "text", "text": "Write a caption for this image"},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image_base64}"}},
],
},
],
"temperature": 0,
}
try:
response = requests.post(api_url, json=payload, headers=headers)
if response.status_code == 200:
return response.json()
else:
st.error(f"API Error: {response.status_code}, {response.text}")
return {"error": response.text}
except Exception as e:
st.error(f"An exception occurred: {e}")
return {"error": str(e)}
# File uploader for image
uploaded_image = st.file_uploader("Upload an image", type=["png", "jpg", "jpeg"])
if uploaded_image and API_KEY:
# Convert the image to base64
image = Image.open(uploaded_image)
buffered = BytesIO()
image.save(buffered, format="PNG")
image_base64 = base64.b64encode(buffered.getvalue()).decode()
# Show the uploaded image
st.image(image, caption="Uploaded Image", use_container_width=True)
# Add a button to trigger caption generation
if st.button("Generate Caption", use_container_width=True):
st.write("Generating caption...")
result = generate_caption(image_base64, API_KEY)
# Extract and display the generated caption
if "error" in result:
st.error(f"Error: {result['error']}")
else:
try:
# Extract the caption from the response
caption = (
result.get("choices", [{}])[0]
.get("message", {})
.get("content", "No caption generated.")
)
st.subheader("Generated Caption")
# Use a text area for the caption so it can be copied easily
caption_area = st.text_area(
"", caption, height=100, key="caption_area", disabled=True,
max_chars=2000, # Limit number of characters for better display
help="The generated caption will appear here.", label_visibility="collapsed"
)
# JavaScript to copy text from the text area
st.markdown(
"""
<script>
function copyText() {
var copyText = document.getElementById("caption_area");
copyText.select();
copyText.setSelectionRange(0, 99999); // For mobile devices
document.execCommand("copy");
}
</script>
""", unsafe_allow_html=True
)
# Add a button to trigger the copy functionality
st.button("Copy Caption", on_click="copyText()")
except Exception as e:
st.error(f"Error processing the response: {e}")
else:
if not API_KEY:
st.warning("Please set the `NEBIUS_API_KEY` environment variable.")
else:
st.info("Please upload an image.")
# Customizing CSS for the text area and button (with blue glowing effect for button)
st.markdown(
"""
<style>
/* Custom styles for the text area */
.css-1w6p6e5 {
background-color: #f0f0f5;
color: #333333;
font-size: 16px;
padding: 10px;
}
/* Glowing blue button styling */
.stButton>button {
background-color: #007bff; /* Blue color */
color: white;
font-size: 16px;
border: none;
border-radius: 4px;
padding: 12px 24px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 123, 255, 0.6), 0 0 10px rgba(0, 123, 255, 0.8);
transition: all 0.3s ease-in-out;
}
.stButton>button:hover {
background-color: #0056b3; /* Darker blue on hover */
box-shadow: 0 4px 6px rgba(0, 123, 255, 0.8), 0 0 20px rgba(0, 123, 255, 1);
}
/* Text area styling */
.stTextArea>div>textarea {
background-color: #f5f5f5;
color: #333;
font-size: 14px;
padding: 10px;
border-radius: 5px;
}
.stTextArea>div>textarea:disabled {
background-color: #e0e0e0;
color: #666;
}
/* Centering elements */
.css-1v3fvcr {
justify-content: center;
display: flex;
}
.css-ffhzg6 {
text-align: center;
}
</style>
""", unsafe_allow_html=True
)
|