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("

๐ŸŽƒ Halloween Photo Booth ๐Ÿ“ธ

", unsafe_allow_html=True) st.markdown("
Capture your Halloween spirit with a festive photo! ๐Ÿ‘ป
", 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