File size: 11,570 Bytes
7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 7c1b343 57eccf2 |
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 |
import streamlit as st
import os
from PIL import Image
from io import BytesIO
import zipfile
from dotenv import load_dotenv
# Import from helper_utilities.py
from utils.helper_utilities import (
get_next_largest_aspect_ratio, draw_crop_preview,
add_custom_message, generate_flux_image
)
# Import from configuration.py
from utils.configuration import (
default_guidance_scale, default_num_inference_steps,
default_seed, holiday_border_prompts, example_holiday_messages, fonts
)
# Streamlit app starts here
st.image("img/fireworksai_logo.png")
st.title("π Holiday Card Customizer π
")
st.markdown("""
β¨ Welcome to the **Holiday Card Generator**! Get ready to sprinkle some holiday magic onto your custom card with a festive border and a heartfelt message. Here's how you can spread the holiday cheer:
1. π **Upload your image** β Select a photo or design to be the star of your holiday card.
2. β¨ **Design your holiday card border** β Choose from seasonal prompts or create your own unique design.
3. π **Add your personal holiday message** β Make it meaningful, funny, or warm-hearted!
4. π¦ **Download your finished card** β Ready to send to friends and family.
Letβs bring your holiday greetings to life! π
""")
# Initialize session state variables
if 'uploaded_file' not in st.session_state:
st.session_state.uploaded_file = None
if 'generated_image' not in st.session_state:
st.session_state.generated_image = None
if 'metadata' not in st.session_state:
st.session_state.metadata = {}
st.divider()
st.subheader("π
Step 1: Load Your Fireworks API Key π")
# Load API Key
# Define and ensure the .env directory and file exist
dotenv_path = os.path.join(os.path.dirname(__file__), '..', 'env', '.env')
os.makedirs(os.path.dirname(dotenv_path), exist_ok=True)
# Create the .env file if it doesn't exist
if not os.path.exists(dotenv_path):
with open(dotenv_path, "w") as f:
st.success(f"Created {dotenv_path}")
# Load environment variables from the .env file
load_dotenv(dotenv_path, override=True)
# Check if the Fireworks API key is set or blank
fireworks_api_key = os.getenv("FIREWORKS_API_KEY")
# Show the entire app but disable running parts if no API key
if not fireworks_api_key or fireworks_api_key.strip() == "":
fireworks_api_key = st.text_input("Enter Fireworks API Key", type="password")
# Optionally, allow the user to save the API key to the .env file
if fireworks_api_key and st.checkbox("Save API key for future use"):
with open(dotenv_path, "a") as f:
f.write(f"FIREWORKS_API_KEY={fireworks_api_key}\n")
st.success("API key saved to .env file.")
else:
st.success(f"API key loaded successfully: partial preview {fireworks_api_key[:5]}")
# Step 1: Upload Image
st.subheader("π Step 2: Upload Your Festive Picture π¨")
st.markdown("""
It's time to pick your image! This will be the centerpiece of your holiday card.
- **Pro Tip**: Choose something that brings out the warmth and joy of the season! ππ
Upload a **PNG** or **JPEG** image to get started.
""")
uploaded_file = st.file_uploader("Upload an image", type=["png", "jpg", "jpeg"])
if uploaded_file is not None:
st.session_state.uploaded_file = uploaded_file
# Process uploaded image
if st.session_state.uploaded_file is not None:
try:
original_image = Image.open(st.session_state.uploaded_file)
st.image(original_image, caption="Uploaded Image", use_column_width=True)
# Step 2: Crop Image
st.subheader("βοΈ Step 3: Trim Your Image Just Right! π")
st.markdown("""
Adjust the crop sliders to capture the most festive part of your image.
A preview will show you how your holiday card is shaping up! β¨
""")
img_width, img_height = original_image.size
col1, col2 = st.columns(2)
with col1:
x_pos = st.slider("X position (Left-Right)", 0, img_width, img_width // 4)
crop_width = st.slider("Width", 10, img_width - x_pos, min(img_width // 2, img_width - x_pos))
with col2:
y_pos = st.slider("Y position (Up-Down)", 0, img_height, img_height // 4)
crop_height = st.slider("Height", 10, img_height - y_pos, min(img_height // 2, img_height - y_pos))
preview_image = draw_crop_preview(original_image.copy(), x_pos, y_pos, crop_width, crop_height)
st.image(preview_image, caption="Crop Preview", use_column_width=True)
# Step 3: Set Border Parameters and Generate Image
st.subheader("π¨ Step 4: Design Your Holiday Border! π
")
st.markdown("""
Choose from a range of holiday themes like snowflakes, cozy fireplaces, or fireworks!
Want to create your own magical scene? Enter a **custom prompt** to make it truly unique! π
""")
selected_prompt = st.selectbox("Choose a holiday-themed prompt or enter your own", options=["Custom"] + holiday_border_prompts)
custom_prompt = st.text_input("Enter your custom prompt") if selected_prompt == "Custom" else ""
prompt = custom_prompt if selected_prompt == "Custom" else selected_prompt
guidance_scale = st.slider("Guidance Scale", min_value=0.0, max_value=20.0, value=default_guidance_scale, step=0.1)
num_inference_steps = st.slider("Number of Inference Steps", min_value=1, max_value=100, value=default_num_inference_steps, step=1)
seed = st.slider("Random Seed", min_value=0, max_value=1000, value=default_seed)
if st.button("Generate Holiday Card"):
if not prompt.strip():
st.error("Please enter a prompt.")
else:
with st.spinner("Adding holiday magic..."):
aspect_ratio = get_next_largest_aspect_ratio(img_width, img_height)
generated_image = generate_flux_image(
model_path="flux-1-schnell-fp8",
api_key=fireworks_api_key,
prompt=prompt,
steps=num_inference_steps,
guidance_scale=guidance_scale,
seed=seed,
aspect_ratio=f"{aspect_ratio[0]}:{aspect_ratio[1]}"
)
if generated_image is not None:
generated_image = generated_image.resize(original_image.size)
cropped_original = original_image.crop((x_pos, y_pos, x_pos + crop_width, y_pos + crop_height))
center_x = (generated_image.width - crop_width) // 2
center_y = (generated_image.height - crop_height) // 2
final_image = generated_image.copy()
final_image.paste(cropped_original, (center_x, center_y))
st.session_state.generated_image = final_image
# Save metadata
st.session_state.metadata = {
"Prompt": prompt,
"Guidance Scale": guidance_scale,
"Inference Steps": num_inference_steps,
"Seed": seed
}
st.image(final_image, caption="π Final Holiday Card π", use_column_width=True)
# Print the metadata below the image
st.markdown("### β¨ Card Metadata")
for key, value in st.session_state.metadata.items():
st.write(f"**{key}:** {value}")
# Step 4: Add Custom Message
if 'generated_image' in st.session_state and st.session_state.generated_image is not None:
st.subheader("π Step 5: Add Your Heartfelt Holiday Message! π
")
st.markdown("""
Select a pre-written festive message or craft your own!
Customize the font, size, and color to make it pop! π
""")
selected_message = st.selectbox("Choose an example holiday message or write your own", options=["Custom"] + example_holiday_messages)
custom_message = st.text_input("Enter your holiday message") if selected_message == "Custom" else selected_message
selected_font = st.selectbox("Choose a font for your message", options=list(fonts.keys()))
font_size = st.slider("Adjust font size", min_value=1, max_value=500, value=100, step=5)
# Slider to choose the max characters per line for text wrapping
max_chars = st.slider("Max characters per line:", min_value=20, max_value=100, value=40)
font_path = fonts[selected_font]
bg_color = st.color_picker("Pick a background color for the text", "#FFFFFF")
font_color = st.color_picker("Pick a font color", "#000000")
alpha = st.slider("Background transparency (0: fully transparent, 255: fully opaque)", 0, 255, 200)
position_vertical = st.radio("Vertical position", ["Top", "Center", "Bottom"])
position_horizontal = st.radio("Horizontal position", ["Left", "Center", "Right"])
if st.button("Generate Holiday Card with Message"):
final_image_with_message = st.session_state.generated_image.copy()
final_image_with_message = add_custom_message(
final_image_with_message,
custom_message,
font_path,
font_size,
position_vertical,
position_horizontal,
max_chars=max_chars,
bg_color=bg_color,
font_color=font_color,
alpha=alpha
)
st.image(final_image_with_message, caption="π Holiday Card with Custom Message π", use_column_width=True)
# Save image and metadata to zip
img_byte_arr = BytesIO()
final_image_with_message.save(img_byte_arr, format="PNG")
img_byte_arr.seek(0)
# Create a zip file containing the image and metadata
zip_buffer = BytesIO()
with zipfile.ZipFile(zip_buffer, "w") as zf:
# Add the image to the zip
zf.writestr("holiday_card_with_message.png", img_byte_arr.getvalue())
# Add the metadata as a text file to the zip
metadata_str = "\n".join([f"{key}: {value}" for key, value in st.session_state.metadata.items()])
zf.writestr("metadata.txt", metadata_str)
zip_buffer.seek(0)
# Step 5: Download as zip
st.download_button(
label="π Download Holiday Card and Metadata as ZIP π",
data=zip_buffer,
file_name="holiday_card_with_message.zip",
mime="application/zip"
)
except OSError:
st.error("The uploaded image seems to be truncated or corrupted. Please try with a different image.")
else:
st.warning("Please upload an image to get started.")
# Footer Section
st.divider()
st.markdown(
"""
Thank you for using the Holiday Card Generator powered by **Fireworks**! π
Share your creations with the world and spread the holiday cheer!
Happy Holidays from the **Fireworks Team**. π₯
"""
) |