Spaces:
Runtime error
Runtime error
updated web app
Browse files- .streamlit/config.toml +4 -0
- app.py +56 -38
.streamlit/config.toml
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[theme]
|
2 |
+
base="light"
|
3 |
+
primaryColor="pink"
|
4 |
+
font="serif"
|
app.py
CHANGED
@@ -11,12 +11,43 @@ import style
|
|
11 |
# utils.py
|
12 |
from utils import *
|
13 |
|
|
|
14 |
st.set_page_config(page_title="Animefy", page_icon="images/animefy_logo.png")
|
15 |
|
16 |
-
model_lock = threading.Lock()
|
17 |
|
18 |
-
#
|
19 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
hide_streamlit = """
|
21 |
<style>
|
22 |
#MainMenu {
|
@@ -31,25 +62,19 @@ hide_streamlit = """
|
|
31 |
button[title='View fullscreen'] {
|
32 |
visibility: hidden;
|
33 |
}
|
|
|
|
|
|
|
|
|
34 |
</style>
|
35 |
"""
|
36 |
st.markdown(hide_streamlit, unsafe_allow_html=True)
|
37 |
|
38 |
-
def imageResCheck (image):
|
39 |
-
# load and preprocess input image as a NumPy array
|
40 |
-
image = np.asarray(load_input_image(image))
|
41 |
-
|
42 |
-
image_height, image_width = image.shape[:2]
|
43 |
-
|
44 |
-
if (image_height <= 2160 and image_width <= 2160):
|
45 |
-
return True
|
46 |
-
else:
|
47 |
-
return False
|
48 |
-
|
49 |
# randomizer. a workaround for clearing the contents of the file_uploader
|
50 |
if 'uploader_key' not in st.session_state:
|
51 |
st.session_state['uploader_key'] = str(randint(1000, 100000000))
|
52 |
|
|
|
53 |
# home page title and caption
|
54 |
st.markdown("""
|
55 |
# ✨ Animefy ✨
|
@@ -65,16 +90,17 @@ page_container = st.empty()
|
|
65 |
# store home page contents inside page_container
|
66 |
home_page = page_container.container()
|
67 |
|
68 |
-
#
|
69 |
home_page.markdown("""
|
70 |
### Step #1: Upload the photo that you would like to process!
|
71 |
""")
|
72 |
|
73 |
-
# just some notes for the user
|
74 |
with home_page.expander("📣 Here are some things to take note of...", expanded=True):
|
75 |
st.write("""
|
76 |
* Do note that AnimeGAN works best with images containing **sceneries without people**.
|
77 |
* For best results, use images that **do not** contain human subjects.
|
|
|
78 |
* Fore more information on AnimeGAN, click [here](https://github.com/TachibanaYoshino/AnimeGAN).
|
79 |
""")
|
80 |
|
@@ -90,7 +116,7 @@ if uploaded_image is not None:
|
|
90 |
else:
|
91 |
isValidImage = False
|
92 |
|
93 |
-
# warning
|
94 |
if uploaded_image is not None and not isValidImage:
|
95 |
st.caption("**Warning:** For better performance, please upload an image that will not exceed a resolution of **2160x2160**.")
|
96 |
|
@@ -106,7 +132,7 @@ if isValidImage:
|
|
106 |
|
107 |
home_page.write("---")
|
108 |
|
109 |
-
#
|
110 |
home_page.markdown("""
|
111 |
### Step #2: Now, select your preferred animation style!
|
112 |
""")
|
@@ -117,7 +143,7 @@ if isValidImage:
|
|
117 |
('Paprika', 'Shinkai', 'Hayao')
|
118 |
)
|
119 |
|
120 |
-
# just some more notes for the user
|
121 |
with home_page.expander("🤔 What are these animation styles?", expanded=False):
|
122 |
st.markdown("""
|
123 |
These styles were derived from the works of various directors! Some of these might be familiar to you:
|
@@ -126,6 +152,8 @@ if isValidImage:
|
|
126 |
* **Hayao** Miyazaki: Spirited Away, My Neighbor Totoro, Princess Mononoke
|
127 |
""")
|
128 |
st.write("---")
|
|
|
|
|
129 |
st.markdown("""
|
130 |
🔍 Here are some sample images for you:
|
131 |
""")
|
@@ -136,6 +164,7 @@ if isValidImage:
|
|
136 |
|
137 |
# stylize image
|
138 |
home_page.markdown("If you're all set, then let's proceed! 😄")
|
|
|
139 |
stylize_btn = home_page.button("Stylize!")
|
140 |
|
141 |
# if "stylize" button is clicked,
|
@@ -143,14 +172,10 @@ if isValidImage:
|
|
143 |
# remove processing page contents
|
144 |
page_container.empty()
|
145 |
|
146 |
-
with st.spinner('Hold on... Please do not close this tab....'):
|
147 |
-
model_lock.acquire()
|
148 |
-
|
149 |
# spinner (while processing image)
|
150 |
with st.spinner('Hold on... Processing your image...'):
|
151 |
# stylize input image and produce output
|
152 |
output_image = style.stylize(anime_style, uploaded_image)
|
153 |
-
model_lock.release()
|
154 |
|
155 |
# step #3
|
156 |
st.markdown("""
|
@@ -177,27 +202,20 @@ if isValidImage:
|
|
177 |
# clamp and channels are used since OpenCV was used in processing the image
|
178 |
st.image(output_image, clamp=True, channels='RGB')
|
179 |
|
180 |
-
col1, col2, col3, col4 = st.columns(
|
181 |
|
182 |
with col1:
|
183 |
pass
|
184 |
with col2:
|
185 |
-
#
|
186 |
-
|
187 |
-
# retry button
|
188 |
-
retry_btn = st.button("Try another image")
|
189 |
|
190 |
-
if retry_btn:
|
191 |
-
page_container.empty()
|
192 |
with col3:
|
193 |
-
#
|
194 |
-
|
|
|
|
|
195 |
# download button
|
196 |
st.download_button('Download Image', byte_encode, 'output.jpg', 'jpg')
|
197 |
-
with col4:
|
198 |
-
pass
|
199 |
|
200 |
-
st.write("---")
|
201 |
-
|
202 |
-
# randomizer. just another workaround.
|
203 |
-
st.session_state['uploader_key'] = str(randint(1000, 100000000))
|
|
|
11 |
# utils.py
|
12 |
from utils import *
|
13 |
|
14 |
+
# tab customization
|
15 |
st.set_page_config(page_title="Animefy", page_icon="images/animefy_logo.png")
|
16 |
|
|
|
17 |
|
18 |
+
# SOME HELPER FUNCTIONS
|
19 |
+
# image resolution checking
|
20 |
+
def imageResCheck (image):
|
21 |
+
# load and preprocess input image as a NumPy array
|
22 |
+
image = np.asarray(load_input_image(image))
|
23 |
+
|
24 |
+
image_height, image_width = image.shape[:2]
|
25 |
+
|
26 |
+
if (image_height <= 2160 and image_width <= 2160):
|
27 |
+
return True
|
28 |
+
else:
|
29 |
+
return False
|
30 |
+
|
31 |
+
# callback when user wants to try another image
|
32 |
+
def tryNewImage ():
|
33 |
+
# to ensure that the new id is unique
|
34 |
+
# -> to ensure that the file uploader will reset
|
35 |
+
while True:
|
36 |
+
# randomizer. work around for resetting file uploader
|
37 |
+
rand_id = str(randint(1000, 100000000))
|
38 |
+
|
39 |
+
if rand_id is not st.session_state['uploader_key']:
|
40 |
+
page_container.empty()
|
41 |
+
st.session_state['uploader_key'] = rand_id
|
42 |
+
break
|
43 |
+
|
44 |
+
# callback when user wants to try another style
|
45 |
+
def tryNewStyle ():
|
46 |
+
# if another_style_btn:
|
47 |
+
page_container.empty()
|
48 |
+
|
49 |
+
# SOME INITIAL SETUP
|
50 |
+
# To hide some default streamlit components and to add some customizations
|
51 |
hide_streamlit = """
|
52 |
<style>
|
53 |
#MainMenu {
|
|
|
62 |
button[title='View fullscreen'] {
|
63 |
visibility: hidden;
|
64 |
}
|
65 |
+
.appview-container {
|
66 |
+
background-image: url("https://drive.google.com/uc?export=view&id=1HbgExEyTd8r6kWhe7JYgihnsXXtZ0Lmm");
|
67 |
+
background-size: cover;
|
68 |
+
}
|
69 |
</style>
|
70 |
"""
|
71 |
st.markdown(hide_streamlit, unsafe_allow_html=True)
|
72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
# randomizer. a workaround for clearing the contents of the file_uploader
|
74 |
if 'uploader_key' not in st.session_state:
|
75 |
st.session_state['uploader_key'] = str(randint(1000, 100000000))
|
76 |
|
77 |
+
# FRONTEND PROPER
|
78 |
# home page title and caption
|
79 |
st.markdown("""
|
80 |
# ✨ Animefy ✨
|
|
|
90 |
# store home page contents inside page_container
|
91 |
home_page = page_container.container()
|
92 |
|
93 |
+
# STEP #1
|
94 |
home_page.markdown("""
|
95 |
### Step #1: Upload the photo that you would like to process!
|
96 |
""")
|
97 |
|
98 |
+
# just some notes for the user in uploading images
|
99 |
with home_page.expander("📣 Here are some things to take note of...", expanded=True):
|
100 |
st.write("""
|
101 |
* Do note that AnimeGAN works best with images containing **sceneries without people**.
|
102 |
* For best results, use images that **do not** contain human subjects.
|
103 |
+
* Due to performance concerns, please upload images that would not exceed a **2160x2160** resolution.
|
104 |
* Fore more information on AnimeGAN, click [here](https://github.com/TachibanaYoshino/AnimeGAN).
|
105 |
""")
|
106 |
|
|
|
116 |
else:
|
117 |
isValidImage = False
|
118 |
|
119 |
+
# warning if uploaded image has an invalid resolution
|
120 |
if uploaded_image is not None and not isValidImage:
|
121 |
st.caption("**Warning:** For better performance, please upload an image that will not exceed a resolution of **2160x2160**.")
|
122 |
|
|
|
132 |
|
133 |
home_page.write("---")
|
134 |
|
135 |
+
# STEP #2
|
136 |
home_page.markdown("""
|
137 |
### Step #2: Now, select your preferred animation style!
|
138 |
""")
|
|
|
143 |
('Paprika', 'Shinkai', 'Hayao')
|
144 |
)
|
145 |
|
146 |
+
# just some more notes for the user regarding the animation styles
|
147 |
with home_page.expander("🤔 What are these animation styles?", expanded=False):
|
148 |
st.markdown("""
|
149 |
These styles were derived from the works of various directors! Some of these might be familiar to you:
|
|
|
152 |
* **Hayao** Miyazaki: Spirited Away, My Neighbor Totoro, Princess Mononoke
|
153 |
""")
|
154 |
st.write("---")
|
155 |
+
|
156 |
+
# example images
|
157 |
st.markdown("""
|
158 |
🔍 Here are some sample images for you:
|
159 |
""")
|
|
|
164 |
|
165 |
# stylize image
|
166 |
home_page.markdown("If you're all set, then let's proceed! 😄")
|
167 |
+
|
168 |
stylize_btn = home_page.button("Stylize!")
|
169 |
|
170 |
# if "stylize" button is clicked,
|
|
|
172 |
# remove processing page contents
|
173 |
page_container.empty()
|
174 |
|
|
|
|
|
|
|
175 |
# spinner (while processing image)
|
176 |
with st.spinner('Hold on... Processing your image...'):
|
177 |
# stylize input image and produce output
|
178 |
output_image = style.stylize(anime_style, uploaded_image)
|
|
|
179 |
|
180 |
# step #3
|
181 |
st.markdown("""
|
|
|
202 |
# clamp and channels are used since OpenCV was used in processing the image
|
203 |
st.image(output_image, clamp=True, channels='RGB')
|
204 |
|
205 |
+
col1, col2, col3, col4 = st.columns([1, 3, 3, 3])
|
206 |
|
207 |
with col1:
|
208 |
pass
|
209 |
with col2:
|
210 |
+
# try another image
|
211 |
+
retry_btn = st.button("New Image", on_click=tryNewImage)
|
|
|
|
|
212 |
|
|
|
|
|
213 |
with col3:
|
214 |
+
# try another style button
|
215 |
+
another_style_btn = st.button("Change Style", on_click=tryNewStyle)
|
216 |
+
|
217 |
+
with col4:
|
218 |
# download button
|
219 |
st.download_button('Download Image', byte_encode, 'output.jpg', 'jpg')
|
|
|
|
|
220 |
|
221 |
+
st.write("---")
|
|
|
|
|
|