Spaces:
Sleeping
Sleeping
File size: 6,074 Bytes
d925554 365db9f d925554 7c52824 7695044 7c52824 7695044 d925554 2351502 a5f16fc 2351502 a5f16fc 7a5f7f3 a5f16fc 7a5f7f3 a5f16fc 2351502 7a5f7f3 2351502 7a5f7f3 2351502 d925554 a5f16fc 1ef93e4 d925554 7695044 d925554 a5f16fc d925554 7695044 ed21b93 7695044 ed21b93 7695044 d925554 7695044 d925554 7695044 d925554 7695044 d925554 7695044 d925554 1ef93e4 d925554 a5f16fc d925554 7695044 d925554 2351502 d925554 1ef93e4 d925554 7695044 d925554 1ef93e4 7a5f7f3 1ef93e4 d925554 7695044 a5f16fc |
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 169 170 |
# app.py
import streamlit as st
import requests
from PIL import Image
from io import BytesIO
from colorthief import ColorThief
import random
import os
# -- API Keys from Hugging Face Secrets --
UNSPLASH_ACCESS_KEY = os.environ.get("UNSPLASH_ACCESS_KEY")
GOOGLE_FONTS_API_KEY = os.environ.get("GOOGLE_FONTS_API_KEY")
st.set_page_config(page_title="Moodboard AI", layout="wide")
# -- Init Session State --
if 'dark_mode' not in st.session_state:
st.session_state.dark_mode = False
if 'generate' not in st.session_state:
st.session_state.generate = False
if 'remix' not in st.session_state:
st.session_state.remix = random.randint(1, 10000)
# -- Dark Mode Toggle (no forced rerun) --
dark_mode_toggle = st.toggle("π Toggle Dark Mode", value=st.session_state.dark_mode, key="dark_toggle")
if dark_mode_toggle != st.session_state.dark_mode:
st.session_state.dark_mode = dark_mode_toggle
st.experimental_rerun()
# -- Apply Dark Mode Styling --
if st.session_state.dark_mode:
st.markdown("""
<style>
body, .stApp {
background-color: #121212;
color: #f0f0f0;
}
h1, h2, h3, h4, h5, h6 {
color: #ffffff !important;
}
.stTextInput > div > div > input,
.stTextArea > div > textarea {
background-color: #222222;
color: #ffffff;
}
.stButton>button {
background-color: #333333;
color: #ffffff;
}
</style>
""", unsafe_allow_html=True)
else:
st.markdown("""
<style>
h1, h2, h3, h4, h5, h6 {
color: #000000 !important;
}
</style>
""", unsafe_allow_html=True)
# -- Title --
st.title("π¨ Moodboard AI β Smart Visual Inspiration Generator")
# -- API Status Display --
if UNSPLASH_ACCESS_KEY:
st.success("β
Unsplash API key loaded successfully.")
else:
st.warning("β οΈ Unsplash API key missing or not set in Hugging Face Secrets.")
if GOOGLE_FONTS_API_KEY:
st.success("β
Google Fonts API key loaded successfully.")
else:
st.warning("β οΈ Google Fonts API key missing or not set in Hugging Face Secrets.")
# -- Theme Input --
theme = st.text_input("Enter a theme or keyword (e.g. 'vintage tech', 'coastal minimalism'):", "futuristic tech").lower()
# -- Control Buttons --
col1, col2 = st.columns(2)
with col1:
if st.button("π Remix Moodboard"):
st.session_state.remix = random.randint(1, 10000)
st.session_state.generate = True
with col2:
if st.button("β¨ Generate Moodboard"):
st.session_state.generate = True
# -- Fetch Images from Unsplash --
def fetch_images_from_unsplash(query, count=5):
if not UNSPLASH_ACCESS_KEY:
st.error("π« Missing Unsplash API Key. Please add it to Hugging Face Secrets.")
return []
try:
url = f"https://api.unsplash.com/search/photos?query={query}&per_page={count}&client_id={UNSPLASH_ACCESS_KEY}"
response = requests.get(url)
if response.status_code != 200:
st.error(f"β Unsplash API Error: {response.status_code}")
return []
data = response.json()
results = data.get('results', [])
if not results:
st.warning("β οΈ Unsplash API returned 0 results. Try a different keyword.")
return [item['urls']['regular'] for item in results]
except Exception as e:
st.error(f"β Error fetching images: {e}")
return []
# -- Extract Dominant Colors --
def extract_colors(image_urls):
colors = []
for url in image_urls[:3]:
try:
response = requests.get(url)
img = BytesIO(response.content)
ct = ColorThief(img)
palette = ct.get_palette(color_count=3)
colors.extend(palette)
except:
continue
return colors[:5]
# -- Fetch Fonts from Google Fonts --
def fetch_google_fonts():
if not GOOGLE_FONTS_API_KEY:
st.error("π« Missing Google Fonts API Key. Please add it to Hugging Face Secrets.")
return []
try:
url = f"https://www.googleapis.com/webfonts/v1/webfonts?sort=popularity&key={GOOGLE_FONTS_API_KEY}"
res = requests.get(url)
data = res.json()
fonts = [item['family'] for item in data.get('items', [])]
return random.sample(fonts, 3)
except Exception as e:
st.error(f"β Error fetching fonts: {e}")
return []
# -- Show Moodboard --
if st.session_state.get("generate"):
with st.spinner("Generating your moodboard..."):
query = f"{theme} {st.session_state.remix}"
image_urls = fetch_images_from_unsplash(query)
if not image_urls:
st.warning("No images found. Try another keyword or check your API key.")
else:
st.subheader("πΌοΈ Image Suggestions")
cols = st.columns(len(image_urls))
for col, url in zip(cols, image_urls):
col.image(url, use_container_width=True)
st.subheader("π¨ Color Palette")
palette = extract_colors(image_urls)
color_cols = st.columns(len(palette))
for col, rgb in zip(color_cols, palette):
hex_color = '#%02x%02x%02x' % rgb
col.markdown(
f"<div style='background-color:{hex_color};height:50px;width:100%;border-radius:5px'></div>",
unsafe_allow_html=True
)
col.write(hex_color)
st.subheader("π€ Font Suggestions")
fonts = fetch_google_fonts()
for font in fonts:
st.markdown(
f"<p style='font-family:{font};font-size:24px;color:{'#ffffff' if st.session_state.dark_mode else '#000000'}'>{font}</p>",
unsafe_allow_html=True
)
st.success("β
Moodboard ready! Right-click or screenshot to save.")
st.session_state.generate = False # Reset |