Spaces:
Sleeping
Sleeping
File size: 9,796 Bytes
14a35b3 8c3cca9 977f082 8c3cca9 14a35b3 977f082 8c3cca9 977f082 2821cf4 977f082 14a35b3 8c3cca9 977f082 8c3cca9 14a35b3 8c3cca9 14a35b3 977f082 8c3cca9 14a35b3 977f082 14a35b3 b4b93f2 14a35b3 2821cf4 977f082 8c3cca9 977f082 8c3cca9 977f082 8c3cca9 977f082 8c3cca9 977f082 8c3cca9 977f082 2821cf4 8c3cca9 977f082 8c3cca9 2821cf4 8c3cca9 977f082 8c3cca9 977f082 8c3cca9 977f082 8c3cca9 977f082 8c3cca9 977f082 8c3cca9 977f082 8c3cca9 977f082 8c3cca9 977f082 8c3cca9 2821cf4 14a35b3 8c3cca9 2821cf4 8c3cca9 2821cf4 8c3cca9 14a35b3 8c3cca9 14a35b3 2821cf4 8c3cca9 2821cf4 8c3cca9 14a35b3 2821cf4 8c3cca9 14a35b3 8c3cca9 977f082 14a35b3 |
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 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
import streamlit as st
import random
from io import BytesIO
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
# ------------------- BRAND CONFIG -------------------
BRAND = "#0F2C59" # Procelevate navy
ACCENT = "#00FFFF" # Cyan glow
PINK = "#FF00FF" # Magenta glow
st.set_page_config(
page_title="AI Name Magic - Procelevate",
page_icon="โจ",
layout="centered",
)
# ------------------- SESSION STATE -------------------
if "gallery" not in st.session_state:
st.session_state.gallery = [] # list of dicts: {"img": bytes, "name": str, "fact": str}
if "current_name" not in st.session_state:
st.session_state.current_name = ""
if "current_fact" not in st.session_state:
st.session_state.current_fact = ""
if "current_card" not in st.session_state:
st.session_state.current_card = None
# ------------------- HEADER (CENTERED LOGO) -------------------
# Try a few common locations for the logo so path changes don't break the app.
logo_candidates = [
"src/procelevate_logo.png",
"src/assets/procelevate_logo.png",
"procelevate_logo.png",
]
logo_path = next((p for p in logo_candidates if Path(p).exists()), None)
if logo_path:
c1, c2, c3 = st.columns([1, 2, 1])
with c2:
st.image(logo_path, width=150)
st.markdown(
f"""
<div style="text-align:center; margin-top:4px;">
<h1 style="margin:0; color:{BRAND};">AI Name Magic โจ</h1>
<div style="font-size:20px; color:#1f2937;">Powered by <b style="color:{BRAND};">Procelevate Consulting</b></div>
</div>
<hr style="opacity:.2;"/>
""",
unsafe_allow_html=True,
)
# ------------------- INPUT FORM -------------------
with st.form("name_form", clear_on_submit=False):
st.subheader("๐ฎ Type Your Name & See AI Magic")
name = st.text_input("Enter your name:")
submitted = st.form_submit_button("Show My AI Prediction ๐")
# ------------------- PREDICTION POOL -------------------
facts = [
"It's a beautiful name...AI predicts youโll be a Future Innovator. Keep rocking..! ๐",
"It's a beautiful name...Your curiosity will power the next big idea. Keep inspiring...! ๐ก",
"It's a beautiful name...You might be the Next Data Scientist / Data Engineer. Best Wishes for you....! ๐",
"It's a beautiful name...AI says youโll shape the Future of Tech. Thank you future CTO...! ๐ค",
"It's a beautiful name...Leadership and technology is in your DNA ๐",
"It's a beautiful name...AI foresees a potential CEO / CTO of a big company ๐",
]
def choose_new_fact(exclude=None):
pool = [f for f in facts if f != exclude] or facts
return random.choice(pool)
# ------------------- IMAGE GENERATOR (PNG CARD) -------------------
def _load_font(path_candidates, size):
"""Try to load a TTF font from common paths; fall back to default."""
for p in path_candidates:
if Path(p).exists():
try:
return ImageFont.truetype(p, size)
except Exception:
pass
return ImageFont.load_default()
def make_card(name_text: str, fact_text: str) -> bytes:
"""Create a branded 'Future Me Card' PNG and return bytes."""
W, H = 1200, 630
base = Image.new("RGB", (W, H), (15, 44, 89)) # #0F2C59
draw = ImageDraw.Draw(base)
# Subtle cyan gradient overlay
grad = Image.new("RGB", (W, H))
for y in range(H):
c = int(255 * (y / H) * 0.18)
grad.putpixel((0, y), (0, 180, 180 - c))
grad = grad.resize((W, H))
base = Image.blend(base, grad, 0.15)
draw = ImageDraw.Draw(base)
# Fonts: try DejaVu (available if installed), else default
dejavu_bold = [
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
"/usr/local/share/fonts/DejaVuSans-Bold.ttf",
]
dejavu = [
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
"/usr/local/share/fonts/DejaVuSans.ttf",
]
title_font = _load_font(dejavu_bold, 70)
name_font = _load_font(dejavu_bold, 120)
fact_font = _load_font(dejavu, 46)
foot_font = _load_font(dejavu, 28)
# Paste logo if available (resolve relative to this file)
try:
local_dir = Path(__file__).parent
lp = None
for cand in ["procelevate_logo.png", "assets/procelevate_logo.png", "../procelevate_logo.png"]:
p = (local_dir / cand).resolve()
if p.exists():
lp = p
break
if lp:
logo = Image.open(lp).convert("RGBA")
logo = logo.resize((140, 140))
base.paste(logo, (50, 50), logo)
except Exception:
pass # OK if logo missing
# Title pill
title = "YOUR AI PREDICTION"
tw = draw.textlength(title, font=title_font)
th = getattr(title_font, "size", 70)
draw.rounded_rectangle([(400, 70), (400 + tw + 60, 70 + th + 40)], radius=18, fill=(255, 255, 255))
draw.text((430, 90), title, font=title_font, fill=(15, 44, 89))
# Neon name
name_text = name_text.upper()
nx, ny = 120, 260
draw.text((nx + 6, ny + 6), name_text, font=name_font, fill=(255, 0, 255)) # magenta shadow
draw.text((nx - 6, ny - 6), name_text, font=name_font, fill=(0, 255, 255)) # cyan shadow
draw.text((nx, ny), name_text, font=name_font, fill=(255, 255, 255)) # white main
# Fact chip
fact_box_y = ny + 170
draw.rounded_rectangle([(80, fact_box_y), (W - 80, fact_box_y + 170)], radius=24, fill=(255, 255, 255))
draw.text((110, fact_box_y + 55), f"โจ {fact_text}", font=fact_font, fill=(15, 44, 89))
# Footer
footer = "ยฉ Procelevate Consulting โข Elevating Processes. Empowering People."
fw = draw.textlength(footer, font=foot_font)
draw.text(((W - fw) // 2, H - 60), footer, font=foot_font, fill=(230, 240, 245))
buf = BytesIO()
base.save(buf, format="PNG")
buf.seek(0)
return buf.getvalue()
# ------------------- RENDER RESULT BLOCK -------------------
def render_result(name_text: str, fact_text: str):
st.markdown(
f"""
<div style="
margin: 10px auto 0 auto;
max-width: 820px;
text-align:center;
padding: 18px 22px;
border-radius: 16px;
background:
radial-gradient(circle at 20% 10%, rgba(0,255,255,.25), transparent 40%),
radial-gradient(circle at 80% 0%, rgba(255,0,255,.25), transparent 35%),
linear-gradient(180deg, #ffffff 0%, #f7fbff 100%);
border: 2px solid #e6eef7;">
<div style="font-size:14px; letter-spacing:1px; color:{BRAND}; font-weight:700;
display:inline-block; padding:6px 12px; border-radius:999px; background:#e6f3ff; margin-bottom:8px;">
YOUR AI PREDICTION
</div>
<h1 style="margin:4px 0 8px 0; font-size:56px; color:{BRAND};
text-shadow: 2px 2px {ACCENT}, -2px -2px {PINK};">
{name_text.upper()}
</h1>
<div style="font-size:22px; color:#0b2239; padding:12px 16px; border-radius:12px;
background:#f0f9ff; display:inline-block;">
โจ {fact_text}
</div>
</div>
""",
unsafe_allow_html=True,
)
# ------------------- HANDLE SUBMIT -------------------
if submitted and name.strip():
st.session_state.current_name = name.strip()
st.session_state.current_fact = choose_new_fact(None)
st.session_state.current_card = make_card(st.session_state.current_name, st.session_state.current_fact)
# Add to gallery (cap 5 latest)
st.session_state.gallery = (st.session_state.gallery + [{
"img": st.session_state.current_card,
"name": st.session_state.current_name,
"fact": st.session_state.current_fact
}])[-5:]
st.balloons()
elif submitted and not name.strip():
st.warning("Please enter your name first ๐")
# ------------------- TRY ANOTHER PREDICTION BUTTON -------------------
# Show only if we already have a name
if st.session_state.current_name:
try_another = st.button("๐ Try another prediction")
if try_another:
st.session_state.current_fact = choose_new_fact(st.session_state.current_fact)
st.session_state.current_card = make_card(st.session_state.current_name, st.session_state.current_fact)
st.session_state.gallery = (st.session_state.gallery + [{
"img": st.session_state.current_card,
"name": st.session_state.current_name,
"fact": st.session_state.current_fact
}])[-5:]
# ------------------- SHOW RESULT (IF ANY) -------------------
if st.session_state.current_name and st.session_state.current_fact:
render_result(st.session_state.current_name, st.session_state.current_fact)
# Download button for the latest card
if st.session_state.current_card:
st.download_button(
"โฌ๏ธ Download My Future Me Card (PNG)",
data=st.session_state.current_card,
file_name=f"{st.session_state.current_name.replace(' ','_')}_future_me.png",
mime="image/png",
)
# ------------------- LIVE GALLERY (LAST 5) -------------------
if st.session_state.gallery:
st.markdown("<hr style='opacity:.15;'/>", unsafe_allow_html=True)
st.subheader("๐ธ Live Gallery (latest 5)")
items = list(reversed(st.session_state.gallery)) # newest first
cols = st.columns(len(items))
for col, item in zip(cols, items):
with col:
st.image(item["img"], caption=item["name"], use_container_width=True)
st.markdown("<hr style='opacity:.2;'/>", unsafe_allow_html=True)
st.markdown(
"<p style='text-align:center; font-size:14px;'>ยฉ 2025 Procelevate Consulting</p>",
unsafe_allow_html=True,
)
|