Spaces:
Runtime error
Runtime error
toilaluan
commited on
Commit
β’
22df377
1
Parent(s):
b7ea0ca
update
Browse files- common.py +40 -0
- core.py +278 -0
- pages/1_π¨_Text_To_Image.py +246 -0
- pages/2_π¨_Image_To_Image.py +190 -0
- pages/3_π¨_Control_To_Image.py +254 -0
common.py
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
BACKGROUND_COLOR = "white"
|
2 |
+
COLOR = "black"
|
3 |
+
|
4 |
+
import streamlit as st
|
5 |
+
|
6 |
+
def set_page_container_style(
|
7 |
+
max_width: int = 1100,
|
8 |
+
max_width_100_percent: bool = False,
|
9 |
+
padding_top: int = 1,
|
10 |
+
padding_right: int = 10,
|
11 |
+
padding_left: int = 1,
|
12 |
+
padding_bottom: int = 10,
|
13 |
+
color: str = COLOR,
|
14 |
+
background_color: str = BACKGROUND_COLOR,
|
15 |
+
):
|
16 |
+
if max_width_100_percent:
|
17 |
+
max_width_str = f"max-width: 100%;"
|
18 |
+
else:
|
19 |
+
max_width_str = f"max-width: {max_width}px;"
|
20 |
+
st.markdown(
|
21 |
+
f"""
|
22 |
+
<style>
|
23 |
+
.reportview-container .css-1lcbmhc .css-1outpf7 {{
|
24 |
+
padding-top: 35px;
|
25 |
+
}}
|
26 |
+
.reportview-container .main .block-container {{
|
27 |
+
{max_width_str}
|
28 |
+
padding-top: {padding_top}rem;
|
29 |
+
padding-right: {padding_right}rem;
|
30 |
+
padding-left: {padding_left}rem;
|
31 |
+
padding-bottom: {padding_bottom}rem;
|
32 |
+
}}
|
33 |
+
.reportview-container .main {{
|
34 |
+
color: {color};
|
35 |
+
background-color: {background_color};
|
36 |
+
}}
|
37 |
+
</style>
|
38 |
+
""",
|
39 |
+
unsafe_allow_html=True,
|
40 |
+
)
|
core.py
ADDED
@@ -0,0 +1,278 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import base64
|
2 |
+
import io
|
3 |
+
import random
|
4 |
+
import time
|
5 |
+
from typing import List
|
6 |
+
from PIL import Image
|
7 |
+
import aiohttp
|
8 |
+
import asyncio
|
9 |
+
import requests
|
10 |
+
import streamlit as st
|
11 |
+
import requests
|
12 |
+
import zipfile
|
13 |
+
import io
|
14 |
+
import pandas as pd
|
15 |
+
from utils import icon
|
16 |
+
from streamlit_image_select import image_select
|
17 |
+
from PIL import Image
|
18 |
+
import random
|
19 |
+
import time
|
20 |
+
import base64
|
21 |
+
from typing import List
|
22 |
+
import aiohttp
|
23 |
+
import asyncio
|
24 |
+
import plotly.express as px
|
25 |
+
from common import set_page_container_style
|
26 |
+
|
27 |
+
|
28 |
+
def pil_image_to_base64(image: Image.Image) -> str:
|
29 |
+
image_stream = io.BytesIO()
|
30 |
+
image.save(image_stream, format="PNG")
|
31 |
+
base64_image = base64.b64encode(image_stream.getvalue()).decode("utf-8")
|
32 |
+
|
33 |
+
return base64_image
|
34 |
+
|
35 |
+
|
36 |
+
def get_or_create_eventloop():
|
37 |
+
try:
|
38 |
+
return asyncio.get_event_loop()
|
39 |
+
except RuntimeError as ex:
|
40 |
+
if "There is no current event loop in thread" in str(ex):
|
41 |
+
loop = asyncio.new_event_loop()
|
42 |
+
asyncio.set_event_loop(loop)
|
43 |
+
return asyncio.get_event_loop()
|
44 |
+
|
45 |
+
|
46 |
+
model_config = {
|
47 |
+
"RealisticVision": {
|
48 |
+
"ratio": {
|
49 |
+
"square": (512, 512),
|
50 |
+
"tall": (512, 768),
|
51 |
+
"wide": (768, 512),
|
52 |
+
},
|
53 |
+
"num_inference_steps": 30,
|
54 |
+
"guidance_scale": 7.0,
|
55 |
+
"clip_skip": 2,
|
56 |
+
},
|
57 |
+
"AnimeV3": {
|
58 |
+
"num_inference_steps": 25,
|
59 |
+
"guidance_scale": 7,
|
60 |
+
"clip_skip": 2,
|
61 |
+
"ratio": {
|
62 |
+
"square": (1024, 1024),
|
63 |
+
"tall": (672, 1024),
|
64 |
+
"wide": (1024, 672),
|
65 |
+
},
|
66 |
+
},
|
67 |
+
"DreamShaper": {
|
68 |
+
"num_inference_steps": 35,
|
69 |
+
"guidance_scale": 7,
|
70 |
+
"clip_skip": 2,
|
71 |
+
"ratio": {
|
72 |
+
"square": (512, 512),
|
73 |
+
"tall": (512, 768),
|
74 |
+
"wide": (768, 512),
|
75 |
+
},
|
76 |
+
},
|
77 |
+
"RealitiesEdgeXL": {
|
78 |
+
"num_inference_steps": 7,
|
79 |
+
"guidance_scale": 2.5,
|
80 |
+
"clip_skip": 2,
|
81 |
+
"ratio": {
|
82 |
+
"square": (1024, 1024),
|
83 |
+
"tall": (672, 1024),
|
84 |
+
"wide": (1024, 672),
|
85 |
+
},
|
86 |
+
},
|
87 |
+
}
|
88 |
+
|
89 |
+
|
90 |
+
def base64_to_image(base64_string):
|
91 |
+
return Image.open(io.BytesIO(base64.b64decode(base64_string)))
|
92 |
+
|
93 |
+
|
94 |
+
async def call_niche_api(url, data) -> List[Image.Image]:
|
95 |
+
try:
|
96 |
+
async with aiohttp.ClientSession() as session:
|
97 |
+
async with session.post(url, json=data) as response:
|
98 |
+
response = await response.json()
|
99 |
+
return base64_to_image(response)
|
100 |
+
except Exception as e:
|
101 |
+
print(e)
|
102 |
+
return None
|
103 |
+
|
104 |
+
|
105 |
+
async def get_output(url, datas):
|
106 |
+
tasks = [asyncio.create_task(call_niche_api(url, data)) for data in datas]
|
107 |
+
return await asyncio.gather(*tasks)
|
108 |
+
|
109 |
+
|
110 |
+
def main_page(
|
111 |
+
submitted: bool,
|
112 |
+
model_name: str,
|
113 |
+
prompt: str,
|
114 |
+
negative_prompt: str,
|
115 |
+
aspect_ratio: str,
|
116 |
+
num_images: int,
|
117 |
+
uid: str,
|
118 |
+
secret_key: str,
|
119 |
+
seed: str,
|
120 |
+
conditional_image: str,
|
121 |
+
controlnet_conditioning_scale: list,
|
122 |
+
pipeline_type: str,
|
123 |
+
api_token: str,
|
124 |
+
generated_images_placeholder,
|
125 |
+
) -> None:
|
126 |
+
"""Main page layout and logic for generating images.
|
127 |
+
|
128 |
+
Args:
|
129 |
+
submitted (bool): Flag indicating whether the form has been submitted.
|
130 |
+
width (int): Width of the output image.
|
131 |
+
height (int): Height of the output image.
|
132 |
+
num_inference_steps (int): Number of denoising steps.
|
133 |
+
guidance_scale (float): Scale for classifier-free guidance.
|
134 |
+
prompt_strength (float): Prompt strength when using img2img/inpaint.
|
135 |
+
prompt (str): Text prompt for the image generation.
|
136 |
+
negative_prompt (str): Text prompt for elements to avoid in the image.
|
137 |
+
"""
|
138 |
+
if submitted:
|
139 |
+
if secret_key != api_token and uid != "-1":
|
140 |
+
st.error("Invalid secret key")
|
141 |
+
return
|
142 |
+
try:
|
143 |
+
uid = int(uid)
|
144 |
+
except ValueError:
|
145 |
+
uid = -1
|
146 |
+
width, height = model_config[model_name]["ratio"][aspect_ratio.lower()]
|
147 |
+
width = int(width)
|
148 |
+
height = int(height)
|
149 |
+
num_inference_steps = model_config[model_name]["num_inference_steps"]
|
150 |
+
guidance_scale = model_config[model_name]["guidance_scale"]
|
151 |
+
|
152 |
+
with st.status(
|
153 |
+
"π©πΎβπ³ Whipping up your words into art...", expanded=True
|
154 |
+
) as status:
|
155 |
+
try:
|
156 |
+
# Only call the API if the "Submit" button was pressed
|
157 |
+
if submitted:
|
158 |
+
start_time = time.time()
|
159 |
+
# Calling the replicate API to get the image
|
160 |
+
with generated_images_placeholder.container():
|
161 |
+
try:
|
162 |
+
seed = int(seed)
|
163 |
+
except ValueError:
|
164 |
+
seed = -1
|
165 |
+
if seed >= 0:
|
166 |
+
seeds = [int(seed) + i for i in range(num_images)]
|
167 |
+
else:
|
168 |
+
seeds = [random.randint(0, 1e9) for _ in range(num_images)]
|
169 |
+
all_images = [] # List to store all generated images
|
170 |
+
data = {
|
171 |
+
"key": api_token,
|
172 |
+
"prompt": prompt, # prompt
|
173 |
+
"model_name": model_name, # See avaialble models in https://github.com/NicheTensor/NicheImage/blob/main/configs/model_config.yaml
|
174 |
+
"seed": seed, # -1 means random seed
|
175 |
+
"miner_uid": int(
|
176 |
+
uid
|
177 |
+
), # specify miner uid, -1 means random miner selected by validator
|
178 |
+
"pipeline_type": pipeline_type,
|
179 |
+
"conditional_image": conditional_image,
|
180 |
+
"pipeline_params": { # params feed to diffusers pipeline, see all params here https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion/text2img#diffusers.StableDiffusionPipeline.__call__
|
181 |
+
"width": width,
|
182 |
+
"height": height,
|
183 |
+
"num_inference_steps": num_inference_steps,
|
184 |
+
"guidance_scale": guidance_scale,
|
185 |
+
"negative_prompt": negative_prompt,
|
186 |
+
"controlnet_conditioning_scale": controlnet_conditioning_scale,
|
187 |
+
"clip_skip": model_config[model_name]["clip_skip"],
|
188 |
+
},
|
189 |
+
}
|
190 |
+
duplicate_data = [data.copy() for _ in range(num_images)]
|
191 |
+
for i, d in enumerate(duplicate_data):
|
192 |
+
d["seed"] = seeds[i]
|
193 |
+
# Call the NicheImage API
|
194 |
+
loop = get_or_create_eventloop()
|
195 |
+
asyncio.set_event_loop(loop)
|
196 |
+
output = loop.run_until_complete(
|
197 |
+
get_output(
|
198 |
+
"http://proxy_client_nicheimage.nichetensor.com:10003/generate",
|
199 |
+
duplicate_data,
|
200 |
+
)
|
201 |
+
)
|
202 |
+
while len(output) < 4:
|
203 |
+
output.append(None)
|
204 |
+
for i, image in enumerate(output):
|
205 |
+
if not image:
|
206 |
+
output[i] = Image.new("RGB", (width, height), (0, 0, 0))
|
207 |
+
print(output)
|
208 |
+
if output:
|
209 |
+
st.toast("Your image has been generated!", icon="π")
|
210 |
+
end_time = time.time()
|
211 |
+
status.update(
|
212 |
+
label=f"β
Images generated in {round(end_time-start_time, 3)} seconds",
|
213 |
+
state="complete",
|
214 |
+
expanded=False,
|
215 |
+
)
|
216 |
+
|
217 |
+
# Save generated image to session state
|
218 |
+
st.session_state.generated_image = output
|
219 |
+
captions = [f"Image {i+1} π" for i in range(4)]
|
220 |
+
all_images = []
|
221 |
+
# Displaying the image
|
222 |
+
_, main_col, _ = st.columns([0.15, 0.7, 0.15])
|
223 |
+
with main_col:
|
224 |
+
cols_1 = st.columns(2)
|
225 |
+
cols_2 = st.columns(2)
|
226 |
+
with st.container(border=True):
|
227 |
+
for i, image in enumerate(
|
228 |
+
st.session_state.generated_image[:2]
|
229 |
+
):
|
230 |
+
cols_1[i].image(
|
231 |
+
image,
|
232 |
+
caption=captions[i],
|
233 |
+
use_column_width=True,
|
234 |
+
output_format="PNG",
|
235 |
+
)
|
236 |
+
# Add image to the list
|
237 |
+
all_images.append(image)
|
238 |
+
for i, image in enumerate(
|
239 |
+
st.session_state.generated_image[2:]
|
240 |
+
):
|
241 |
+
cols_2[i].image(
|
242 |
+
image,
|
243 |
+
caption=captions[i + 2],
|
244 |
+
use_column_width=True,
|
245 |
+
output_format="PNG",
|
246 |
+
)
|
247 |
+
|
248 |
+
# Save all generated images to session state
|
249 |
+
st.session_state.all_images = all_images
|
250 |
+
zip_io = io.BytesIO()
|
251 |
+
# Download option for each image
|
252 |
+
with zipfile.ZipFile(zip_io, "w") as zipf:
|
253 |
+
for i, image in enumerate(st.session_state.all_images):
|
254 |
+
image_data = io.BytesIO()
|
255 |
+
image.save(image_data, format="PNG")
|
256 |
+
image_data.seek(0)
|
257 |
+
# Write each image to the zip file with a name
|
258 |
+
zipf.writestr(
|
259 |
+
f"output_file_{i+1}.png", image_data.read()
|
260 |
+
)
|
261 |
+
# Create a download button for the zip file
|
262 |
+
st.download_button(
|
263 |
+
":red[**Download All Images**]",
|
264 |
+
data=zip_io.getvalue(),
|
265 |
+
file_name="output_files.zip",
|
266 |
+
mime="application/zip",
|
267 |
+
use_container_width=True,
|
268 |
+
)
|
269 |
+
status.update(
|
270 |
+
label="β
Images generated!", state="complete", expanded=False
|
271 |
+
)
|
272 |
+
except Exception as e:
|
273 |
+
print(e)
|
274 |
+
st.error(f"Encountered an error: {e}", icon="π¨")
|
275 |
+
|
276 |
+
# If not submitted, chill here πΉ
|
277 |
+
else:
|
278 |
+
pass
|
pages/1_π¨_Text_To_Image.py
ADDED
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import base64
|
3 |
+
import io
|
4 |
+
import random
|
5 |
+
import time
|
6 |
+
from typing import List
|
7 |
+
from PIL import Image
|
8 |
+
import aiohttp
|
9 |
+
import asyncio
|
10 |
+
from streamlit_image_select import image_select
|
11 |
+
import requests
|
12 |
+
import streamlit as st
|
13 |
+
import requests
|
14 |
+
import zipfile
|
15 |
+
import io
|
16 |
+
import pandas as pd
|
17 |
+
from core import *
|
18 |
+
from utils import icon
|
19 |
+
from streamlit_image_select import image_select
|
20 |
+
from PIL import Image
|
21 |
+
import random
|
22 |
+
import time
|
23 |
+
import base64
|
24 |
+
from typing import List
|
25 |
+
import aiohttp
|
26 |
+
import asyncio
|
27 |
+
import plotly.express as px
|
28 |
+
from common import set_page_container_style
|
29 |
+
|
30 |
+
replicate_text = "NicheImage - Subnet 23 - Bittensor"
|
31 |
+
replicate_logo = "assets/NicheTensorTransparent.png"
|
32 |
+
replicate_link = "https://github.com/NicheTensor/NicheImage"
|
33 |
+
|
34 |
+
st.set_page_config(
|
35 |
+
page_title="NicheImage Generator", page_icon=replicate_logo, layout="wide"
|
36 |
+
)
|
37 |
+
set_page_container_style(
|
38 |
+
max_width=1100,
|
39 |
+
max_width_100_percent=True,
|
40 |
+
padding_top=0,
|
41 |
+
padding_right=10,
|
42 |
+
padding_left=5,
|
43 |
+
padding_bottom=10,
|
44 |
+
)
|
45 |
+
|
46 |
+
|
47 |
+
def get_or_create_eventloop():
|
48 |
+
try:
|
49 |
+
return asyncio.get_event_loop()
|
50 |
+
except RuntimeError as ex:
|
51 |
+
if "There is no current event loop in thread" in str(ex):
|
52 |
+
loop = asyncio.new_event_loop()
|
53 |
+
asyncio.set_event_loop(loop)
|
54 |
+
return asyncio.get_event_loop()
|
55 |
+
|
56 |
+
|
57 |
+
# UI configurations
|
58 |
+
st.markdown(
|
59 |
+
"""<style>
|
60 |
+
#root > div:nth-child(1) > div > div > div > div > section > div {padding-top: 2rem;}
|
61 |
+
</style>
|
62 |
+
|
63 |
+
""",
|
64 |
+
unsafe_allow_html=True,
|
65 |
+
)
|
66 |
+
css = """
|
67 |
+
<style>
|
68 |
+
section.main > div:has(~ footer ) {
|
69 |
+
padding-bottom: 5px;
|
70 |
+
}
|
71 |
+
</style>
|
72 |
+
"""
|
73 |
+
st.markdown(css, unsafe_allow_html=True)
|
74 |
+
|
75 |
+
# API Tokens and endpoints from `.streamlit/secrets.toml` file
|
76 |
+
API_TOKEN = st.secrets["API_TOKEN"]
|
77 |
+
# Placeholders for images and gallery
|
78 |
+
generated_images_placeholder = st.empty()
|
79 |
+
gallery_placeholder = st.empty()
|
80 |
+
|
81 |
+
|
82 |
+
def configure_sidebar() -> None:
|
83 |
+
"""
|
84 |
+
Setup and display the sidebar elements.
|
85 |
+
|
86 |
+
This function configures the sidebar of the Streamlit application,
|
87 |
+
including the form for user inputs and the resources section.
|
88 |
+
"""
|
89 |
+
with st.sidebar:
|
90 |
+
st.image(replicate_logo, use_column_width=True)
|
91 |
+
with st.form("my_form"):
|
92 |
+
model_name = st.selectbox(
|
93 |
+
":blue[**Select Model**]",
|
94 |
+
options=[
|
95 |
+
"RealisticVision",
|
96 |
+
"AnimeV3",
|
97 |
+
"DreamShaper",
|
98 |
+
"RealitiesEdgeXL",
|
99 |
+
],
|
100 |
+
)
|
101 |
+
prompt = st.text_area(
|
102 |
+
":blue[**Enter prompt βπΎ**]",
|
103 |
+
value="cinematic still of a shiba inu, fluffy neck, wearing a suit of ornate metal armor",
|
104 |
+
)
|
105 |
+
aspect_ratio = st.selectbox(
|
106 |
+
":blue[**Aspect Ratio**]", options=["Tall", "Wide", "Square"]
|
107 |
+
)
|
108 |
+
num_images = 4
|
109 |
+
negative_prompt = st.text_area(
|
110 |
+
":blue[**Negative Prompt π
π½ββοΈ**]",
|
111 |
+
value="low quality, blurry, pixelated, noisy, low resolution, defocused, out of focus, overexposed, bad image, nsfw",
|
112 |
+
help="This is a negative prompt, basically type what you don't want to see in the generated image",
|
113 |
+
)
|
114 |
+
with st.expander(
|
115 |
+
"π Advanced",
|
116 |
+
expanded=False,
|
117 |
+
):
|
118 |
+
uid = st.text_input("Specify an UID", value="-1")
|
119 |
+
secret_key = st.text_input("Enter secret key", value="")
|
120 |
+
seed = st.text_input("Seed", value="-1")
|
121 |
+
# The Big Red "Submit" Button!
|
122 |
+
submitted = st.form_submit_button(
|
123 |
+
"Submit", type="primary", use_container_width=True
|
124 |
+
)
|
125 |
+
|
126 |
+
return (
|
127 |
+
submitted,
|
128 |
+
model_name,
|
129 |
+
prompt,
|
130 |
+
negative_prompt,
|
131 |
+
aspect_ratio,
|
132 |
+
num_images,
|
133 |
+
uid,
|
134 |
+
secret_key,
|
135 |
+
seed,
|
136 |
+
"",
|
137 |
+
)
|
138 |
+
|
139 |
+
|
140 |
+
def main():
|
141 |
+
"""
|
142 |
+
Main function to run the Streamlit application.
|
143 |
+
|
144 |
+
This function initializes the sidebar configuration and the main page layout.
|
145 |
+
It retrieves the user inputs from the sidebar, and passes them to the main page function.
|
146 |
+
The main page function then generates images based on these inputs.
|
147 |
+
"""
|
148 |
+
(
|
149 |
+
submitted,
|
150 |
+
model_name,
|
151 |
+
prompt,
|
152 |
+
negative_prompt,
|
153 |
+
aspect_ratio,
|
154 |
+
num_images,
|
155 |
+
uid,
|
156 |
+
secret_key,
|
157 |
+
seed,
|
158 |
+
conditional_image,
|
159 |
+
) = configure_sidebar()
|
160 |
+
main_page(
|
161 |
+
submitted,
|
162 |
+
model_name,
|
163 |
+
prompt,
|
164 |
+
negative_prompt,
|
165 |
+
aspect_ratio,
|
166 |
+
num_images,
|
167 |
+
uid,
|
168 |
+
secret_key,
|
169 |
+
seed,
|
170 |
+
conditional_image,
|
171 |
+
[],
|
172 |
+
"txt2img",
|
173 |
+
API_TOKEN,
|
174 |
+
generated_images_placeholder,
|
175 |
+
)
|
176 |
+
if not submitted:
|
177 |
+
with gallery_placeholder.container():
|
178 |
+
with st.container():
|
179 |
+
st.info(
|
180 |
+
"π©πΎβπ³ :blue[**Realistic Vision Style - [CivitAI](https://civitai.com/models/4201/realistic-vision-v60-b1)**]"
|
181 |
+
)
|
182 |
+
st.balloons()
|
183 |
+
with st.container(border=True):
|
184 |
+
_ = image_select(
|
185 |
+
label="",
|
186 |
+
images=[
|
187 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/401d2674-e1f8-4976-a615-36110d0b76b3/original=true/ref-res-1.jpeg",
|
188 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/d2050c06-e916-4091-857a-66bdafcaf6d9/original=true/00029-913302605.jpeg",
|
189 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/0012d0e9-6d77-4981-b16e-13ac9f3eeb53/original=true/00011-836818560.jpeg",
|
190 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/088542b8-00dc-4135-8115-f2086ebb4ffb/original=true/06772-2405195618-HDR,UHD,8K,Highly%20detailed,best%20quality,masterpiece,_lora_catman_0.8_,maomi,blurry%20background,blurry,sunglasses,hat,hands%20in%20poc.jpeg",
|
191 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/3b23b565-9b7b-4e5b-9a40-ff9b5e80565d/original=true/00076-329187343.jpeg",
|
192 |
+
],
|
193 |
+
use_container_width=False,
|
194 |
+
)
|
195 |
+
with st.container():
|
196 |
+
st.info(
|
197 |
+
"π©πΎβπ³ :blue[**DreamShaper Style - [CivitAI](https://civitai.com/models/4384/dreamshaper)**]"
|
198 |
+
)
|
199 |
+
with st.container(border=True):
|
200 |
+
_ = image_select(
|
201 |
+
label="",
|
202 |
+
images=[
|
203 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/af837eea-2ccc-4801-b916-75ecb270c382/original=true/71584-4007479174-masterpiece,%20a%20dinosaur%20(in%20the%20museum_1.2),%20background%20is%20museum%20exhibition,%20(art%20by%20YRAX_1.1),%20saturated%20colors,%20concept%20art,.jpeg",
|
204 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/77940ee3-062a-4d2b-95c4-52c69b79fffd/original=true/00524-2430470379.jpeg",
|
205 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/1649bcd9-4417-4c83-97f8-674373b67d61/original=true/42445-1548916933-wabstyle,%20monochrome,%20_lora_wabstyle_1_%20a%20dog.jpeg",
|
206 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/09264ecb-38c6-42ed-a2f7-a7ab5ab662fb/original=true/00262-5775713%20-%20Kopie.jpeg",
|
207 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/a25faadc-7370-426d-9e95-1e102a10e508/original=true/00613-787076454-(a%20Glass%20ring_1.3),%20masterpiece,%20best%20quality,%20_lora_RingArt_Sora_0.8_,%20(style%20of%20Ellen%20Gallagher_1.3)__(masterpiece,%20best%20quali%20(1).jpeg",
|
208 |
+
],
|
209 |
+
use_container_width=False,
|
210 |
+
)
|
211 |
+
with st.container():
|
212 |
+
st.info(
|
213 |
+
"π©πΎβπ³ :blue[**AnimeV3 Style - [CivitAI](https://civitai.com/models/146113/newdream-sdxl)**]"
|
214 |
+
)
|
215 |
+
with st.container(border=True):
|
216 |
+
_ = image_select(
|
217 |
+
label="",
|
218 |
+
images=[
|
219 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/c788e346-7af1-4135-928a-c944634a4a51/original=true/Soldier.jpeg",
|
220 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/dc86e78e-7587-45b8-b709-b6f611af68fa/original=true/pirate%20(3).jpeg",
|
221 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/cb6aa6c4-6cd6-4efd-84a8-4b3917ca4d24/original=true/00000-1761366536.jpeg",
|
222 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/61cad059-f9d8-446f-b33d-b22e078ac5fb/original=true/Scream.jpeg",
|
223 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/58d55973-12c9-4854-afbc-4fbd8f5434ef/original=true/CarSakura.jpeg",
|
224 |
+
],
|
225 |
+
use_container_width=False,
|
226 |
+
)
|
227 |
+
with st.container():
|
228 |
+
st.info(
|
229 |
+
"π©πΎβπ³ :blue[**RealitiesEdgeXL Style - [CivitAI](https://civitai.com/models/129666?modelVersionId=356472)**]"
|
230 |
+
)
|
231 |
+
with st.container(border=True):
|
232 |
+
_ = image_select(
|
233 |
+
label="",
|
234 |
+
images=[
|
235 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/7ae8de93-3634-4fb2-acb6-7ba66a630670/original=true/00044-3526680654.jpeg",
|
236 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/d7a3e977-5433-46d0-82ba-4946386bd28e/original=true/00135-1518921975.jpeg",
|
237 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/c3852385-4c73-4821-ac6f-b9f0323c7d6f/original=true/08323--3358745561.jpeg",
|
238 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/7f6be0cf-4b58-4c16-aa8f-4c396fb135b2/original=true/ComfyUI-1-_01583_.jpeg",
|
239 |
+
"https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/e9ecf8ad-8f3b-4fc3-9eca-c59389e84a3f/original=true/08314--1054985950.jpeg",
|
240 |
+
],
|
241 |
+
use_container_width=False,
|
242 |
+
)
|
243 |
+
|
244 |
+
|
245 |
+
if __name__ == "__main__":
|
246 |
+
main()
|
pages/2_π¨_Image_To_Image.py
ADDED
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import base64
|
3 |
+
import io
|
4 |
+
import random
|
5 |
+
import time
|
6 |
+
from typing import List
|
7 |
+
from PIL import Image
|
8 |
+
import aiohttp
|
9 |
+
import asyncio
|
10 |
+
import requests
|
11 |
+
import streamlit as st
|
12 |
+
import requests
|
13 |
+
import zipfile
|
14 |
+
import io
|
15 |
+
import pandas as pd
|
16 |
+
from core import *
|
17 |
+
from utils import icon
|
18 |
+
from streamlit_image_select import image_select
|
19 |
+
from PIL import Image
|
20 |
+
import random
|
21 |
+
import time
|
22 |
+
import base64
|
23 |
+
from typing import List
|
24 |
+
import aiohttp
|
25 |
+
import asyncio
|
26 |
+
import plotly.express as px
|
27 |
+
from common import set_page_container_style
|
28 |
+
|
29 |
+
replicate_text = "NicheImage - Subnet 23 - Bittensor"
|
30 |
+
replicate_logo = "assets/NicheTensorTransparent.png"
|
31 |
+
replicate_link = "https://github.com/NicheTensor/NicheImage"
|
32 |
+
|
33 |
+
st.set_page_config(
|
34 |
+
page_title="NicheImage Generator", page_icon=replicate_logo, layout="wide"
|
35 |
+
)
|
36 |
+
set_page_container_style(
|
37 |
+
max_width=1100,
|
38 |
+
max_width_100_percent=True,
|
39 |
+
padding_top=0,
|
40 |
+
padding_right=10,
|
41 |
+
padding_left=5,
|
42 |
+
padding_bottom=10,
|
43 |
+
)
|
44 |
+
|
45 |
+
|
46 |
+
def get_or_create_eventloop():
|
47 |
+
try:
|
48 |
+
return asyncio.get_event_loop()
|
49 |
+
except RuntimeError as ex:
|
50 |
+
if "There is no current event loop in thread" in str(ex):
|
51 |
+
loop = asyncio.new_event_loop()
|
52 |
+
asyncio.set_event_loop(loop)
|
53 |
+
return asyncio.get_event_loop()
|
54 |
+
|
55 |
+
|
56 |
+
# UI configurations
|
57 |
+
st.markdown(
|
58 |
+
"""<style>
|
59 |
+
#root > div:nth-child(1) > div > div > div > div > section > div {padding-top: 2rem;}
|
60 |
+
</style>
|
61 |
+
|
62 |
+
""",
|
63 |
+
unsafe_allow_html=True,
|
64 |
+
)
|
65 |
+
css = """
|
66 |
+
<style>
|
67 |
+
section.main > div:has(~ footer ) {
|
68 |
+
padding-bottom: 5px;
|
69 |
+
}
|
70 |
+
</style>
|
71 |
+
"""
|
72 |
+
st.markdown(css, unsafe_allow_html=True)
|
73 |
+
|
74 |
+
# API Tokens and endpoints from `.streamlit/secrets.toml` file
|
75 |
+
API_TOKEN = st.secrets["API_TOKEN"]
|
76 |
+
# Placeholders for images and gallery
|
77 |
+
generated_images_placeholder = st.empty()
|
78 |
+
gallery_placeholder = st.empty()
|
79 |
+
|
80 |
+
|
81 |
+
def configure_sidebar() -> None:
|
82 |
+
"""
|
83 |
+
Setup and display the sidebar elements.
|
84 |
+
|
85 |
+
This function configures the sidebar of the Streamlit application,
|
86 |
+
including the form for user inputs and the resources section.
|
87 |
+
"""
|
88 |
+
with st.sidebar:
|
89 |
+
st.image(replicate_logo, use_column_width=True)
|
90 |
+
with st.form("my_form"):
|
91 |
+
model_name = st.selectbox(
|
92 |
+
":blue[**Select Model**]",
|
93 |
+
options=["DreamShaper"],
|
94 |
+
)
|
95 |
+
prompt = st.text_area(
|
96 |
+
":blue[**Enter prompt βπΎ**]",
|
97 |
+
value="cinematic still of a shiba inu, fluffy neck, wearing a suit of ornate metal armor",
|
98 |
+
)
|
99 |
+
# aspect_ratio = st.selectbox(
|
100 |
+
# ":blue[**Aspect Ratio**]", options=["Tall", "Wide", "Square"]
|
101 |
+
# )
|
102 |
+
aspect_ratio = "Square"
|
103 |
+
conditional_image = st.file_uploader(
|
104 |
+
":blue[**Upload your image**]",
|
105 |
+
type=["png", "jpg", "jpeg"],
|
106 |
+
help="Upload an image to condition the generation",
|
107 |
+
)
|
108 |
+
if conditional_image:
|
109 |
+
st.image(conditional_image)
|
110 |
+
# num_images = st.slider(":blue[**Number of images to generate**]", 1, 4, 1)
|
111 |
+
num_images = 4
|
112 |
+
negative_prompt = st.text_area(
|
113 |
+
":blue[**Negative Prompt π
π½ββοΈ**]",
|
114 |
+
value="low quality, blurry, pixelated, noisy, low resolution, defocused, out of focus, overexposed, bad image, nsfw",
|
115 |
+
help="This is a negative prompt, basically type what you don't want to see in the generated image",
|
116 |
+
)
|
117 |
+
with st.expander(
|
118 |
+
"π Advanced",
|
119 |
+
expanded=False,
|
120 |
+
):
|
121 |
+
uid = st.text_input("Specify an UID", value="-1")
|
122 |
+
secret_key = st.text_input("Enter secret key", value="")
|
123 |
+
seed = st.text_input("Seed", value="-1")
|
124 |
+
# The Big Red "Submit" Button!
|
125 |
+
submitted = st.form_submit_button(
|
126 |
+
"Submit", type="primary", use_container_width=True
|
127 |
+
)
|
128 |
+
|
129 |
+
return (
|
130 |
+
submitted,
|
131 |
+
model_name,
|
132 |
+
prompt,
|
133 |
+
negative_prompt,
|
134 |
+
aspect_ratio,
|
135 |
+
num_images,
|
136 |
+
uid,
|
137 |
+
secret_key,
|
138 |
+
seed,
|
139 |
+
conditional_image,
|
140 |
+
)
|
141 |
+
|
142 |
+
|
143 |
+
def main():
|
144 |
+
"""
|
145 |
+
Main function to run the Streamlit application.
|
146 |
+
|
147 |
+
This function initializes the sidebar configuration and the main page layout.
|
148 |
+
It retrieves the user inputs from the sidebar, and passes them to the main page function.
|
149 |
+
The main page function then generates images based on these inputs.
|
150 |
+
"""
|
151 |
+
(
|
152 |
+
submitted,
|
153 |
+
model_name,
|
154 |
+
prompt,
|
155 |
+
negative_prompt,
|
156 |
+
aspect_ratio,
|
157 |
+
num_images,
|
158 |
+
uid,
|
159 |
+
secret_key,
|
160 |
+
seed,
|
161 |
+
conditional_image,
|
162 |
+
) = configure_sidebar()
|
163 |
+
if conditional_image:
|
164 |
+
conditional_image = Image.open(conditional_image)
|
165 |
+
conditional_image = pil_image_to_base64(conditional_image)
|
166 |
+
main_page(
|
167 |
+
submitted,
|
168 |
+
model_name,
|
169 |
+
prompt,
|
170 |
+
negative_prompt,
|
171 |
+
aspect_ratio,
|
172 |
+
num_images,
|
173 |
+
uid,
|
174 |
+
secret_key,
|
175 |
+
seed,
|
176 |
+
conditional_image,
|
177 |
+
[],
|
178 |
+
"img2img",
|
179 |
+
API_TOKEN,
|
180 |
+
generated_images_placeholder,
|
181 |
+
)
|
182 |
+
if not submitted:
|
183 |
+
st.info("π¨ Upload your image and imagine the possibilities!")
|
184 |
+
st.image(
|
185 |
+
"https://preview.redd.it/using-crude-drawings-for-composition-img2img-v0-v7adchf52oha1.jpg?auto=webp&s=1251ed1c567a04ec0cf17fe257fbac01b2d903bd"
|
186 |
+
)
|
187 |
+
|
188 |
+
|
189 |
+
if __name__ == "__main__":
|
190 |
+
main()
|
pages/3_π¨_Control_To_Image.py
ADDED
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import base64
|
3 |
+
import io
|
4 |
+
import random
|
5 |
+
import time
|
6 |
+
from typing import List
|
7 |
+
from PIL import Image
|
8 |
+
import aiohttp
|
9 |
+
import asyncio
|
10 |
+
import requests
|
11 |
+
import streamlit as st
|
12 |
+
import requests
|
13 |
+
import zipfile
|
14 |
+
import io
|
15 |
+
import pandas as pd
|
16 |
+
from core import *
|
17 |
+
from utils import icon
|
18 |
+
from streamlit_image_select import image_select
|
19 |
+
from PIL import Image
|
20 |
+
import random
|
21 |
+
import time
|
22 |
+
import base64
|
23 |
+
from typing import List
|
24 |
+
import aiohttp
|
25 |
+
import asyncio
|
26 |
+
import plotly.express as px
|
27 |
+
from common import set_page_container_style
|
28 |
+
|
29 |
+
replicate_text = "NicheImage - Subnet 23 - Bittensor"
|
30 |
+
replicate_logo = "assets/NicheTensorTransparent.png"
|
31 |
+
replicate_link = "https://github.com/NicheTensor/NicheImage"
|
32 |
+
|
33 |
+
st.set_page_config(
|
34 |
+
page_title="NicheImage Generator", page_icon=replicate_logo, layout="wide"
|
35 |
+
)
|
36 |
+
set_page_container_style(
|
37 |
+
max_width=1100,
|
38 |
+
max_width_100_percent=True,
|
39 |
+
padding_top=0,
|
40 |
+
padding_right=10,
|
41 |
+
padding_left=5,
|
42 |
+
padding_bottom=10,
|
43 |
+
)
|
44 |
+
|
45 |
+
|
46 |
+
def get_or_create_eventloop():
|
47 |
+
try:
|
48 |
+
return asyncio.get_event_loop()
|
49 |
+
except RuntimeError as ex:
|
50 |
+
if "There is no current event loop in thread" in str(ex):
|
51 |
+
loop = asyncio.new_event_loop()
|
52 |
+
asyncio.set_event_loop(loop)
|
53 |
+
return asyncio.get_event_loop()
|
54 |
+
|
55 |
+
|
56 |
+
# UI configurations
|
57 |
+
st.markdown(
|
58 |
+
"""<style>
|
59 |
+
#root > div:nth-child(1) > div > div > div > div > section > div {padding-top: 2rem;}
|
60 |
+
</style>
|
61 |
+
|
62 |
+
""",
|
63 |
+
unsafe_allow_html=True,
|
64 |
+
)
|
65 |
+
css = """
|
66 |
+
<style>
|
67 |
+
section.main > div:has(~ footer ) {
|
68 |
+
padding-bottom: 5px;
|
69 |
+
}
|
70 |
+
</style>
|
71 |
+
"""
|
72 |
+
st.markdown(css, unsafe_allow_html=True)
|
73 |
+
|
74 |
+
# API Tokens and endpoints from `.streamlit/secrets.toml` file
|
75 |
+
API_TOKEN = st.secrets["API_TOKEN"]
|
76 |
+
# Placeholders for images and gallery
|
77 |
+
generated_images_placeholder = st.empty()
|
78 |
+
gallery_placeholder = st.empty()
|
79 |
+
|
80 |
+
|
81 |
+
def configure_sidebar() -> None:
|
82 |
+
"""
|
83 |
+
Setup and display the sidebar elements.
|
84 |
+
|
85 |
+
This function configures the sidebar of the Streamlit application,
|
86 |
+
including the form for user inputs and the resources section.
|
87 |
+
"""
|
88 |
+
with st.sidebar:
|
89 |
+
st.image(replicate_logo, use_column_width=True)
|
90 |
+
with st.form("my_form"):
|
91 |
+
model_name = st.selectbox(
|
92 |
+
":blue[**Select Model**]",
|
93 |
+
options=["DreamShaper"],
|
94 |
+
)
|
95 |
+
prompt = st.text_area(
|
96 |
+
":blue[**Enter prompt βπΎ**]",
|
97 |
+
value="cinematic still of a shiba inu, fluffy neck, wearing a suit of ornate metal armor",
|
98 |
+
)
|
99 |
+
aspect_ratio = "Square"
|
100 |
+
conditional_image = st.file_uploader(
|
101 |
+
":blue[**Upload your image**]",
|
102 |
+
type=["png", "jpg", "jpeg"],
|
103 |
+
help="Upload an image to condition the generation",
|
104 |
+
)
|
105 |
+
if conditional_image:
|
106 |
+
st.image(conditional_image)
|
107 |
+
with st.container(border=True):
|
108 |
+
canny_strength = st.slider(
|
109 |
+
":blue[**Canny Strength**]",
|
110 |
+
min_value=0.0,
|
111 |
+
max_value=1.0,
|
112 |
+
value=0.5,
|
113 |
+
step=0.01,
|
114 |
+
help="Strength of the Canny ControlNet",
|
115 |
+
)
|
116 |
+
depth_strength = st.slider(
|
117 |
+
":blue[**Depth Strength**]",
|
118 |
+
min_value=0.0,
|
119 |
+
max_value=1.0,
|
120 |
+
value=0.5,
|
121 |
+
step=0.01,
|
122 |
+
help="Strength of the Depth ControlNet",
|
123 |
+
)
|
124 |
+
mlsd_strength = st.slider(
|
125 |
+
":blue[**MLSD Strength**]",
|
126 |
+
min_value=0.0,
|
127 |
+
max_value=1.0,
|
128 |
+
value=0.5,
|
129 |
+
step=0.01,
|
130 |
+
help="Strength of the MLSD ControlNet",
|
131 |
+
)
|
132 |
+
controlnet_conditioning_scale = [
|
133 |
+
canny_strength,
|
134 |
+
depth_strength,
|
135 |
+
mlsd_strength,
|
136 |
+
]
|
137 |
+
|
138 |
+
num_images = 4
|
139 |
+
negative_prompt = st.text_area(
|
140 |
+
":blue[**Negative Prompt π
π½ββοΈ**]",
|
141 |
+
value="low quality, blurry, pixelated, noisy, low resolution, defocused, out of focus, overexposed, bad image, nsfw",
|
142 |
+
help="This is a negative prompt, basically type what you don't want to see in the generated image",
|
143 |
+
)
|
144 |
+
with st.expander(
|
145 |
+
"π Advanced",
|
146 |
+
expanded=False,
|
147 |
+
):
|
148 |
+
uid = st.text_input("Specify an UID", value="-1")
|
149 |
+
secret_key = st.text_input("Enter secret key", value="")
|
150 |
+
seed = st.text_input("Seed", value="-1")
|
151 |
+
# The Big Red "Submit" Button!
|
152 |
+
submitted = st.form_submit_button(
|
153 |
+
"Submit", type="primary", use_container_width=True
|
154 |
+
)
|
155 |
+
|
156 |
+
return (
|
157 |
+
submitted,
|
158 |
+
model_name,
|
159 |
+
prompt,
|
160 |
+
negative_prompt,
|
161 |
+
aspect_ratio,
|
162 |
+
num_images,
|
163 |
+
uid,
|
164 |
+
secret_key,
|
165 |
+
seed,
|
166 |
+
conditional_image,
|
167 |
+
controlnet_conditioning_scale,
|
168 |
+
)
|
169 |
+
|
170 |
+
|
171 |
+
def main():
|
172 |
+
"""
|
173 |
+
Main function to run the Streamlit application.
|
174 |
+
|
175 |
+
This function initializes the sidebar configuration and the main page layout.
|
176 |
+
It retrieves the user inputs from the sidebar, and passes them to the main page function.
|
177 |
+
The main page function then generates images based on these inputs.
|
178 |
+
"""
|
179 |
+
(
|
180 |
+
submitted,
|
181 |
+
model_name,
|
182 |
+
prompt,
|
183 |
+
negative_prompt,
|
184 |
+
aspect_ratio,
|
185 |
+
num_images,
|
186 |
+
uid,
|
187 |
+
secret_key,
|
188 |
+
seed,
|
189 |
+
conditional_image,
|
190 |
+
controlnet_conditioning_scale,
|
191 |
+
) = configure_sidebar()
|
192 |
+
if conditional_image:
|
193 |
+
conditional_image = Image.open(conditional_image)
|
194 |
+
conditional_image = pil_image_to_base64(conditional_image)
|
195 |
+
main_page(
|
196 |
+
submitted,
|
197 |
+
model_name,
|
198 |
+
prompt,
|
199 |
+
negative_prompt,
|
200 |
+
aspect_ratio,
|
201 |
+
num_images,
|
202 |
+
uid,
|
203 |
+
secret_key,
|
204 |
+
seed,
|
205 |
+
conditional_image,
|
206 |
+
controlnet_conditioning_scale,
|
207 |
+
"controlnet_txt2img",
|
208 |
+
API_TOKEN,
|
209 |
+
generated_images_placeholder,
|
210 |
+
)
|
211 |
+
if not submitted:
|
212 |
+
with generated_images_placeholder.container():
|
213 |
+
st.info("π¨ :blue[**Canny Edge**]")
|
214 |
+
cols = st.columns(2)
|
215 |
+
with cols[0]:
|
216 |
+
st.image(
|
217 |
+
"https://huggingface.co/takuma104/controlnet_dev/resolve/main/gen_compare/control_images/converted/control_bird_canny.png",
|
218 |
+
use_column_width=True,
|
219 |
+
)
|
220 |
+
with cols[1]:
|
221 |
+
st.image(
|
222 |
+
"https://cdn-lfs.huggingface.co/repos/f4/f7/f4f7a7f70b5d098c5f2b46c19c2063eea26d6eba1488e9141804f6402b509cbb/3907d804ef04bcc1dd998ddb8dbd01ad6ffd071d6f13bd2e8a03936f7fe35f13?response-content-disposition=inline%3B+filename*%3DUTF-8%27%27output_bird_canny_1.png%3B+filename%3D%22output_bird_canny_1.png%22%3B&response-content-type=image%2Fpng&Expires=1709913845&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTcwOTkxMzg0NX19LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy5odWdnaW5nZmFjZS5jby9yZXBvcy9mNC9mNy9mNGY3YTdmNzBiNWQwOThjNWYyYjQ2YzE5YzIwNjNlZWEyNmQ2ZWJhMTQ4OGU5MTQxODA0ZjY0MDJiNTA5Y2JiLzM5MDdkODA0ZWYwNGJjYzFkZDk5OGRkYjhkYmQwMWFkNmZmZDA3MWQ2ZjEzYmQyZThhMDM5MzZmN2ZlMzVmMTM%7EcmVzcG9uc2UtY29udGVudC1kaXNwb3NpdGlvbj0qJnJlc3BvbnNlLWNvbnRlbnQtdHlwZT0qIn1dfQ__&Signature=JplN20XzO7Y34tz-FkA3-cv4VRfIkzz9Tf8-Re7EdW-7%7EaBEItVnl5SDX44oSk-WeNFPfhcHg-b7RK1zlD6H1n3Zo7Y8JtMR1Z07%7ElZ6S6s80j1vpOrMmnkyB-7DcM9Mvi2ITDPXhOdYGnAK1GER1Zdg-ctVEkf7frNEj%7E5zcqJ1kFyRCJcjPHtgAtIAySOANk6BIZEWLEbZGM3b4swTMnNPUZZw5CYRp2dgGgVEo8i6xalR1l8rqvAxQ3yB4C5nfJURcqQLY1lkk9B58dhR6Afy5ZG-krqilv07R7HqbsS7GWq6w8BCEXA0E9cjQTqzqlpCZG0wH78vNE8GDdF6kQ__&Key-Pair-Id=KVTP0A1DKRTAX",
|
223 |
+
use_column_width=True,
|
224 |
+
)
|
225 |
+
st.info("π¨ :blue[**Depth Map**]")
|
226 |
+
cols2 = st.columns(2)
|
227 |
+
with st.container():
|
228 |
+
with cols2[0]:
|
229 |
+
st.image(
|
230 |
+
"https://huggingface.co/takuma104/controlnet_dev/resolve/main/gen_compare/control_images/converted/control_vermeer_depth.png",
|
231 |
+
use_column_width=True,
|
232 |
+
)
|
233 |
+
with cols2[1]:
|
234 |
+
st.image(
|
235 |
+
"https://cdn-lfs.huggingface.co/repos/f4/f7/f4f7a7f70b5d098c5f2b46c19c2063eea26d6eba1488e9141804f6402b509cbb/25c89f31165aa3c435b28deeb1e542c68b0dab496727403c1f3c7ded3b78fdd1?response-content-disposition=inline%3B+filename*%3DUTF-8%27%27output_vermeer_depth_2.png%3B+filename%3D%22output_vermeer_depth_2.png%22%3B&response-content-type=image%2Fpng&Expires=1709913950&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTcwOTkxMzk1MH19LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy5odWdnaW5nZmFjZS5jby9yZXBvcy9mNC9mNy9mNGY3YTdmNzBiNWQwOThjNWYyYjQ2YzE5YzIwNjNlZWEyNmQ2ZWJhMTQ4OGU5MTQxODA0ZjY0MDJiNTA5Y2JiLzI1Yzg5ZjMxMTY1YWEzYzQzNWIyOGRlZWIxZTU0MmM2OGIwZGFiNDk2NzI3NDAzYzFmM2M3ZGVkM2I3OGZkZDE%7EcmVzcG9uc2UtY29udGVudC1kaXNwb3NpdGlvbj0qJnJlc3BvbnNlLWNvbnRlbnQtdHlwZT0qIn1dfQ__&Signature=b%7EhyTb-HRh2shXtGNEfhNrXU%7EsuQdyE0iTXVKpR76CDxlS147%7EYxiU%7E9JJAL1asz-vfUS5u%7ErtqIRfGkKAcU1DP8lqtGhIfDBi6iPNEyWoAWAGj7mF6y50qj7xeq2Iz4yWeHoiZpzotiWbMqCE6V6QKrHsaU2btHlHjlLsw4owh3ELXjHB6%7ENCKwH0uKLfABOBZzrOJOCilJU8VwiCRsk3QryLD3uywZMGDxyzd1vxnaBR4PTIrZ46FEatcXCpGdZ1ZJngtdiepdLRX4tI41gVk0fWYrQ5wOnMSudCQuCfVXvHRnoPwKUVcmF5mCa7smZykizITEmwg3ctW4W80pBA__&Key-Pair-Id=KVTP0A1DKRTAX",
|
236 |
+
use_column_width=True,
|
237 |
+
)
|
238 |
+
st.info("π¨ :blue[**MLSD**]")
|
239 |
+
cols3 = st.columns(2)
|
240 |
+
with st.container():
|
241 |
+
with cols3[0]:
|
242 |
+
st.image(
|
243 |
+
"https://huggingface.co/takuma104/controlnet_dev/resolve/main/gen_compare/control_images/converted/control_room_mlsd.png",
|
244 |
+
use_column_width=True,
|
245 |
+
)
|
246 |
+
with cols3[1]:
|
247 |
+
st.image(
|
248 |
+
"https://cdn-lfs.huggingface.co/repos/f4/f7/f4f7a7f70b5d098c5f2b46c19c2063eea26d6eba1488e9141804f6402b509cbb/92c95cf788f547ef7ea2da0fb45a0232864899ddd93c8f04d88b04f681216ad3?response-content-disposition=inline%3B+filename*%3DUTF-8%27%27output_room_mlsd_0.png%3B+filename%3D%22output_room_mlsd_0.png%22%3B&response-content-type=image%2Fpng&Expires=1709912870&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTcwOTkxMjg3MH19LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy5odWdnaW5nZmFjZS5jby9yZXBvcy9mNC9mNy9mNGY3YTdmNzBiNWQwOThjNWYyYjQ2YzE5YzIwNjNlZWEyNmQ2ZWJhMTQ4OGU5MTQxODA0ZjY0MDJiNTA5Y2JiLzkyYzk1Y2Y3ODhmNTQ3ZWY3ZWEyZGEwZmI0NWEwMjMyODY0ODk5ZGRkOTNjOGYwNGQ4OGIwNGY2ODEyMTZhZDM%7EcmVzcG9uc2UtY29udGVudC1kaXNwb3NpdGlvbj0qJnJlc3BvbnNlLWNvbnRlbnQtdHlwZT0qIn1dfQ__&Signature=A9jKF1jw8YO8OFuB7CzbaeQrEdT8wuPZJnT%7E1gZTxBAot9-HBQypW4IMsP7XPCeWnfdJBH4EKcsfzP2RU2-y2%7ENHrJl6wd9n-Wyi5traDPUgoHlSGIe6BvEKJlkzUI7gf87ThVWNc6wI3kHZM0l3dESE0ID2e2aCKGNxUCfaV%7EBdyt-Myr0HbVQtfYR8SjW7Rdj5WCJy9vOZKS3y2nzfPsUZRNtup4Xw3EW%7Ei0BGomdrB%7EfoOj4A0CvuL-La8SxPz1a3AcakD0ti8P0TPIJ9FrjmWLr49t9gJvn2XMYD3mH8VVsSBsGDn6pjgTLS4FK0KvCu-lIqt14v1bF10wCzBA__&Key-Pair-Id=KVTP0A1DKRTAX",
|
249 |
+
use_column_width=True,
|
250 |
+
)
|
251 |
+
|
252 |
+
|
253 |
+
if __name__ == "__main__":
|
254 |
+
main()
|