BillyZ1129 commited on
Commit
e48bf39
Β·
verified Β·
1 Parent(s): 326a4ec

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +196 -0
app.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ import io
4
+ import torch
5
+ from transformers import BlipProcessor, BlipForConditionalGeneration, pipeline
6
+ from gtts import gTTS
7
+ import os
8
+ import base64
9
+ import time
10
+
11
+ # Set page configuration
12
+ st.set_page_config(
13
+ page_title="Storyteller for Kids",
14
+ page_icon="πŸ“š",
15
+ layout="centered"
16
+ )
17
+
18
+ # Custom CSS
19
+ st.markdown("""
20
+ <style>
21
+ .main {
22
+ background-color: #f5f7ff;
23
+ }
24
+ .stTitle {
25
+ color: #3366cc;
26
+ font-family: 'Comic Sans MS', cursive;
27
+ }
28
+ .stHeader {
29
+ font-family: 'Comic Sans MS', cursive;
30
+ }
31
+ .stImage {
32
+ border-radius: 15px;
33
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
34
+ }
35
+ .story-container {
36
+ background-color: #e6f2ff;
37
+ padding: 20px;
38
+ border-radius: 10px;
39
+ border: 2px dashed #3366cc;
40
+ font-size: 18px;
41
+ line-height: 1.6;
42
+ }
43
+ </style>
44
+ """, unsafe_allow_html=True)
45
+
46
+ # Title and description
47
+ st.title("🧸 Kid's Storyteller 🧸")
48
+ st.markdown("### Upload an image and I'll tell you a magical story about it!")
49
+
50
+ # Function to load image captioning model
51
+ @st.cache_resource
52
+ def load_caption_model():
53
+ try:
54
+ with st.spinner("Loading image captioning model... (This may take a minute)"):
55
+ processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
56
+ model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
57
+ return processor, model, None
58
+ except Exception as e:
59
+ return None, None, str(e)
60
+
61
+ # Function to load story generation model
62
+ @st.cache_resource
63
+ def load_story_model():
64
+ try:
65
+ with st.spinner("Loading story generation model... (This may take a minute)"):
66
+ story_generator = pipeline("text-generation", model="gpt2")
67
+ return story_generator, None
68
+ except Exception as e:
69
+ return None, str(e)
70
+
71
+ # Function to generate caption from image
72
+ def generate_caption(image, processor, model):
73
+ inputs = processor(image, return_tensors="pt")
74
+ out = model.generate(**inputs, max_length=50)
75
+ caption = processor.decode(out[0], skip_special_tokens=True)
76
+ return caption
77
+
78
+ # Function to generate story from caption
79
+ def generate_story(caption, story_generator):
80
+ # Make the prompt child-friendly and whimsical
81
+ prompt = f"Once upon a time in a magical land, {caption}. The children were amazed when "
82
+
83
+ result = story_generator(prompt, max_length=150, num_return_sequences=1, temperature=0.8)
84
+ story = result[0]['generated_text']
85
+
86
+ # Make sure the story is between 50-100 words
87
+ story_words = story.split()
88
+ if len(story_words) > 100:
89
+ story = ' '.join(story_words[:100])
90
+ # Add a closing sentence
91
+ story += ". And they all lived happily ever after."
92
+ elif len(story_words) < 50:
93
+ # If too short, generate more
94
+ additional = story_generator(story, max_length=150, num_return_sequences=1)
95
+ story = additional[0]['generated_text']
96
+ story_words = story.split()
97
+ if len(story_words) > 100:
98
+ story = ' '.join(story_words[:100])
99
+ story += ". And they all lived happily ever after."
100
+
101
+ return story
102
+
103
+ # Function to convert text to speech and create audio player
104
+ def text_to_speech(text):
105
+ try:
106
+ tts = gTTS(text=text, lang='en', slow=False)
107
+ audio_file = "story_audio.mp3"
108
+ tts.save(audio_file)
109
+
110
+ # Create audio player
111
+ with open(audio_file, "rb") as file:
112
+ audio_bytes = file.read()
113
+
114
+ audio_b64 = base64.b64encode(audio_bytes).decode()
115
+ audio_player = f"""
116
+ <audio controls autoplay>
117
+ <source src="data:audio/mp3;base64,{audio_b64}" type="audio/mp3">
118
+ Your browser does not support the audio element.
119
+ </audio>
120
+ """
121
+ return audio_player, None
122
+ except Exception as e:
123
+ return None, str(e)
124
+
125
+ # Main application flow
126
+ try:
127
+ # Load models with status checks
128
+ with st.spinner("Loading AI models... This may take a moment the first time you run the app."):
129
+ caption_processor, caption_model, caption_error = load_caption_model()
130
+ story_model, story_error = load_story_model()
131
+
132
+ if caption_error:
133
+ st.error(f"Error loading caption model: {caption_error}")
134
+ if story_error:
135
+ st.error(f"Error loading story model: {story_error}")
136
+
137
+ # If models loaded successfully
138
+ if caption_processor and caption_model and story_model:
139
+ # Show example images for kids to understand
140
+ st.markdown("### 🌟 Examples of images you can upload:")
141
+ col1, col2, col3 = st.columns(3)
142
+ with col1:
143
+ st.markdown("🐱 Pets")
144
+ with col2:
145
+ st.markdown("🏰 Places")
146
+ with col3:
147
+ st.markdown("🧩 Toys")
148
+
149
+ # File uploader
150
+ uploaded_file = st.file_uploader("Choose an image", type=["jpg", "jpeg", "png"])
151
+
152
+ if uploaded_file is not None:
153
+ # Display the uploaded image
154
+ image_bytes = uploaded_file.getvalue()
155
+ image = Image.open(io.BytesIO(image_bytes))
156
+ st.image(image, caption='Uploaded Image', use_column_width=True, output_format="JPEG")
157
+
158
+ with st.spinner('Creating your story... πŸ“'):
159
+ # Generate caption
160
+ caption = generate_caption(image, caption_processor, caption_model)
161
+
162
+ # Generate story
163
+ story = generate_story(caption, story_model)
164
+
165
+ # Display the story with some styling
166
+ st.markdown("## πŸ“– Your Magical Story")
167
+ st.markdown(f"<div class='story-container'>{story}</div>",
168
+ unsafe_allow_html=True)
169
+
170
+ # Convert to speech and play
171
+ st.markdown("## πŸ”Š Listen to the Story")
172
+ audio_player, audio_error = text_to_speech(story)
173
+
174
+ if audio_player:
175
+ st.markdown(audio_player, unsafe_allow_html=True)
176
+ else:
177
+ st.error(f"Could not generate audio: {audio_error}")
178
+
179
+ # Download options
180
+ st.download_button(
181
+ label="Download Story (Text)",
182
+ data=story,
183
+ file_name="my_story.txt",
184
+ mime="text/plain"
185
+ )
186
+ else:
187
+ st.warning("Some AI models didn't load correctly. Please refresh the page or try again later.")
188
+
189
+ except Exception as e:
190
+ st.error(f"An error occurred: {e}")
191
+ st.markdown("Please try again with a different image.")
192
+
193
+ # Footer
194
+ st.markdown("---")
195
+ st.markdown("Created for young storytellers aged 3-10 years old 🌈")
196
+ st.markdown("Powered by Hugging Face Transformers πŸ€—")