Files
Buffteks-Website/webpages/adminpages/helloween_image.py
2025-10-13 23:50:53 -05:00

124 lines
5.4 KiB
Python

import streamlit as st
from PIL import Image
from google import genai
import json
from io import BytesIO
from .email_helloween_image import send_email_with_attachment
def camera_photo():
st.markdown("<h1 style='text-align: center; color: #451002;'>🎃 Halloween Photo Booth 📸</h1>", unsafe_allow_html=True)
st.markdown("<h5 style='text-align: center;'> Capture your Halloween spirit with a festive photo! 👻 </h3>", unsafe_allow_html=True)
if 'image_response' not in st.session_state:
st.session_state.image_response = None
enable_camera = st.checkbox("Enable Camera")
if enable_camera:
st.info("📎Note: No photos are stored. The image is processed in-memory and deleted after refresh app.")
picture = st.camera_input("Take a Halloween-themed photo! 🎃👻🕸️")
if picture is not None:
image = Image.open(picture)
keep_dressing_style = st.checkbox("Keep original dressing style", value=False)
keep_body_pose = st.checkbox("Keep original body pose", value=False)
theme = st.selectbox(
"Select or Input a Halloween theme for your photo:",
[ "🎃 Classic Halloween",
"👻 Haunted House",
"⚗️ Science Experiment Gone Wrong",
"🎥 Horror Film Inspired",
"🕯️ Gothic",
"🧙‍♂️ Harry Potter",
"⚰️ Graveyard",
"🔮 Cult Horror Theme"
],
index=0,
key="theme_selector"
)
if st.button("AI Editing"):
edit_prompt = f"""
Retain original facial features (eyes, nose, mouth etc.) of any persons in the photo. The goal is to achieve a realistic, edited look, not an AI-generated or overly smoothed/perfected appearance. Avoid any artificial alterations to these features.
Keep the original dressing style: {str(keep_dressing_style)}
Keep the original body pose: {str(keep_body_pose)}
Theme: {theme}
If a person is already in costume, enhance the costume and add more Halloween elements and background to the scene.
If multiple persons are present, ensure all are included in the Halloween theme.
- Overall Style: The final image should be photorealistic.
Ensure the final image is vibrant, festive, and captures the Halloween spirit!
"""
with st.spinner("Editing image..."):
text_response, image_response = edit_image_with_ai(image, edit_prompt)
if text_response:
st.info(text_response)
if image_response:
st.session_state.image_response = image_response
# Rerun to display the generated image and send options
st.rerun()
if st.session_state.image_response:
st.image(st.session_state.image_response)
# Convert PIL image to bytes for download
img_byte_arr = BytesIO()
st.session_state.image_response.save(img_byte_arr, format="JPEG")
st.download_button(
label="Download Edited Image",
data=img_byte_arr.getvalue(),
file_name="edited_image.jpeg",
mime="image/jpeg"
)
send_image(st.session_state.image_response)
def send_image(image_response):
st.divider()
to_email = st.text_input("Enter your email to receive the photo:", key="email_input")
if st.button("Send Email"):
with st.spinner("Sending email..."):
if to_email and image_response:
with open('app_config.json') as config_file:
config = json.load(config_file)
sender_email = config["send_email"]["sender_email"]
password = config["send_email"]["password"]
subject = "Your Spooktacular Halloween Photo! 🎃👻"
send_email_with_attachment(sender_email, password, to_email, subject, image_response)
st.success("Email sent successfully!")
else:
st.error("Please enter a valid email address and ensure the image is generated.")
def edit_image_with_ai(image, description):
with open('app_config.json') as config_file:
config = json.load(config_file)
api_key = config["nano-banana"]["api_key"]
client = genai.Client(api_key=api_key)
prompt = description
response = client.models.generate_content(
model="gemini-2.5-flash-image-preview",
contents=[prompt, image],
)
text_response = None
image_response = None
# AttributeError: 'NoneType' object has no attribute 'parts'
if response.candidates and len(response.candidates) <= 0:
st.error("No response from AI model. Please try again.")
return text_response, image_response
for part in response.candidates[0].content.parts:
if part.text is not None:
text_response = part.text
if part.inline_data is not None:
image_response = Image.open(BytesIO(part.inline_data.data))
return text_response, image_response