Spaces:
Running
Running
add related py file
Browse files- README.md +1 -1
- ui_functions.py +240 -0
README.md
CHANGED
|
@@ -4,7 +4,7 @@ emoji: π
|
|
| 4 |
colorFrom: purple
|
| 5 |
colorTo: gray
|
| 6 |
sdk: gradio
|
| 7 |
-
sdk_version: 3.
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
license: creativeml-openrail-m
|
|
|
|
| 4 |
colorFrom: purple
|
| 5 |
colorTo: gray
|
| 6 |
sdk: gradio
|
| 7 |
+
sdk_version: 3.10.1
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
license: creativeml-openrail-m
|
ui_functions.py
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import re
|
| 2 |
+
import gradio as gr
|
| 3 |
+
from PIL import Image, ImageFont, ImageDraw, ImageFilter, ImageOps
|
| 4 |
+
from io import BytesIO
|
| 5 |
+
import base64
|
| 6 |
+
import re
|
| 7 |
+
|
| 8 |
+
def change_img_choices(sample_size):
|
| 9 |
+
choices = []
|
| 10 |
+
for i in range(int(sample_size)):
|
| 11 |
+
choices.append(
|
| 12 |
+
'εΎη{}(img{})'.format(i+1,i+1)
|
| 13 |
+
)
|
| 14 |
+
update_choices = gr.update(choices=choices)
|
| 15 |
+
return update_choices
|
| 16 |
+
|
| 17 |
+
def change_image_editor_mode(choice, cropped_image, masked_image, resize_mode, width, height):
|
| 18 |
+
if choice == "Mask":
|
| 19 |
+
update_image_result = update_image_mask(cropped_image, resize_mode, width, height)
|
| 20 |
+
return [gr.update(visible=False), update_image_result, gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=True), gr.update(visible=True)]
|
| 21 |
+
|
| 22 |
+
update_image_result = update_image_mask(masked_image["image"] if masked_image is not None else None, resize_mode, width, height)
|
| 23 |
+
return [update_image_result, gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)]
|
| 24 |
+
|
| 25 |
+
def update_image_mask(cropped_image, resize_mode, width, height):
|
| 26 |
+
resized_cropped_image = resize_image(resize_mode, cropped_image, width, height) if cropped_image else None
|
| 27 |
+
return gr.update(value=resized_cropped_image, visible=True)
|
| 28 |
+
|
| 29 |
+
def toggle_options_gfpgan(selection):
|
| 30 |
+
if 0 in selection:
|
| 31 |
+
return gr.update(visible=True)
|
| 32 |
+
else:
|
| 33 |
+
return gr.update(visible=False)
|
| 34 |
+
|
| 35 |
+
def toggle_options_upscalers(selection):
|
| 36 |
+
if 1 in selection:
|
| 37 |
+
return gr.update(visible=True)
|
| 38 |
+
else:
|
| 39 |
+
return gr.update(visible=False)
|
| 40 |
+
|
| 41 |
+
def toggle_options_realesrgan(selection):
|
| 42 |
+
if selection == 0 or selection == 1 or selection == 3:
|
| 43 |
+
return gr.update(visible=True)
|
| 44 |
+
else:
|
| 45 |
+
return gr.update(visible=False)
|
| 46 |
+
|
| 47 |
+
def toggle_options_gobig(selection):
|
| 48 |
+
if selection == 1:
|
| 49 |
+
#print(selection)
|
| 50 |
+
return gr.update(visible=True)
|
| 51 |
+
if selection == 3:
|
| 52 |
+
return gr.update(visible=True)
|
| 53 |
+
else:
|
| 54 |
+
return gr.update(visible=False)
|
| 55 |
+
|
| 56 |
+
def toggle_options_ldsr(selection):
|
| 57 |
+
if selection == 2 or selection == 3:
|
| 58 |
+
return gr.update(visible=True)
|
| 59 |
+
else:
|
| 60 |
+
return gr.update(visible=False)
|
| 61 |
+
|
| 62 |
+
def increment_down(value):
|
| 63 |
+
return value - 1
|
| 64 |
+
|
| 65 |
+
def increment_up(value):
|
| 66 |
+
return value + 1
|
| 67 |
+
|
| 68 |
+
def copy_img_to_lab(img):
|
| 69 |
+
try:
|
| 70 |
+
image_data = re.sub('^data:image/.+;base64,', '', img)
|
| 71 |
+
processed_image = Image.open(BytesIO(base64.b64decode(image_data)))
|
| 72 |
+
tab_update = gr.update(selected='imgproc_tab')
|
| 73 |
+
img_update = gr.update(value=processed_image)
|
| 74 |
+
return processed_image, tab_update,
|
| 75 |
+
except IndexError:
|
| 76 |
+
return [None, None]
|
| 77 |
+
def copy_img_params_to_lab(params):
|
| 78 |
+
try:
|
| 79 |
+
prompt = params[0][0].replace('\n', ' ').replace('\r', '')
|
| 80 |
+
seed = int(params[1][1])
|
| 81 |
+
steps = int(params[7][1])
|
| 82 |
+
cfg_scale = float(params[9][1])
|
| 83 |
+
sampler = params[11][1]
|
| 84 |
+
return prompt,seed,steps,cfg_scale,sampler
|
| 85 |
+
except IndexError:
|
| 86 |
+
return [None, None]
|
| 87 |
+
def copy_img_to_input(img, idx):
|
| 88 |
+
try:
|
| 89 |
+
# print(img)
|
| 90 |
+
# print("=============")
|
| 91 |
+
# print("The img type is:{}".format(type(img[0])))
|
| 92 |
+
idx_map = {
|
| 93 |
+
"εΎη1(img1)":0,
|
| 94 |
+
"εΎη2(img2)":1,
|
| 95 |
+
"εΎη3(img3)":2,
|
| 96 |
+
"εΎη4(img4)":3,
|
| 97 |
+
}
|
| 98 |
+
idx = idx_map[idx]
|
| 99 |
+
assert img[idx]['is_file']
|
| 100 |
+
processed_image = Image.open(img[idx]['name'])
|
| 101 |
+
tab_update = gr.update(selected='img2img_tab')
|
| 102 |
+
move_prompt_zh_update = gr.update(visible=True)
|
| 103 |
+
move_prompt_en_update = gr.update(visible=True)
|
| 104 |
+
prompt_update = gr.update(visible=True)
|
| 105 |
+
return tab_update, processed_image, move_prompt_zh_update, move_prompt_en_update, prompt_update
|
| 106 |
+
except IndexError as e:
|
| 107 |
+
raise gr.Error(e)
|
| 108 |
+
return [None, None, None, None, None]
|
| 109 |
+
|
| 110 |
+
def copy_img_to_edit(img):
|
| 111 |
+
try:
|
| 112 |
+
image_data = re.sub('^data:image/.+;base64,', '', img)
|
| 113 |
+
processed_image = Image.open(BytesIO(base64.b64decode(image_data)))
|
| 114 |
+
tab_update = gr.update(selected='img2img_tab')
|
| 115 |
+
img_update = gr.update(value=processed_image)
|
| 116 |
+
mode_update = gr.update(value='Crop')
|
| 117 |
+
return processed_image, tab_update, mode_update
|
| 118 |
+
except IndexError:
|
| 119 |
+
return [None, None]
|
| 120 |
+
|
| 121 |
+
def copy_img_to_mask(img):
|
| 122 |
+
try:
|
| 123 |
+
image_data = re.sub('^data:image/.+;base64,', '', img)
|
| 124 |
+
processed_image = Image.open(BytesIO(base64.b64decode(image_data)))
|
| 125 |
+
tab_update = gr.update(selected='img2img_tab')
|
| 126 |
+
img_update = gr.update(value=processed_image)
|
| 127 |
+
mode_update = gr.update(value='Mask')
|
| 128 |
+
return processed_image, tab_update, mode_update
|
| 129 |
+
except IndexError:
|
| 130 |
+
return [None, None]
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
def copy_img_to_upscale_esrgan(img):
|
| 135 |
+
tabs_update = gr.update(selected='realesrgan_tab')
|
| 136 |
+
image_data = re.sub('^data:image/.+;base64,', '', img)
|
| 137 |
+
processed_image = Image.open(BytesIO(base64.b64decode(image_data)))
|
| 138 |
+
return processed_image, tabs_update
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
help_text = """
|
| 142 |
+
## Mask/Crop
|
| 143 |
+
* Masking is not inpainting. You will probably get better results manually masking your images in photoshop instead.
|
| 144 |
+
* Built-in masking/cropping is very temperamental.
|
| 145 |
+
* It may take some time for the image to show when switching from Crop to Mask.
|
| 146 |
+
* If the image doesn't appear after switching to Mask, switch back to Crop and then back again to Mask
|
| 147 |
+
* If the mask appears distorted (the brush is weirdly shaped instead of round), switch back to Crop and then back again to Mask.
|
| 148 |
+
|
| 149 |
+
## Advanced Editor
|
| 150 |
+
* Click πΎ Save to send your editor changes to the img2img workflow
|
| 151 |
+
* Click β Clear to discard your editor changes
|
| 152 |
+
|
| 153 |
+
If anything breaks, try switching modes again, switch tabs, clear the image, or reload.
|
| 154 |
+
"""
|
| 155 |
+
|
| 156 |
+
def resize_image(resize_mode, im, width, height):
|
| 157 |
+
LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS)
|
| 158 |
+
if resize_mode == 0:
|
| 159 |
+
res = im.resize((width, height), resample=LANCZOS)
|
| 160 |
+
elif resize_mode == 1:
|
| 161 |
+
ratio = width / height
|
| 162 |
+
src_ratio = im.width / im.height
|
| 163 |
+
|
| 164 |
+
src_w = width if ratio > src_ratio else im.width * height // im.height
|
| 165 |
+
src_h = height if ratio <= src_ratio else im.height * width // im.width
|
| 166 |
+
|
| 167 |
+
resized = im.resize((src_w, src_h), resample=LANCZOS)
|
| 168 |
+
res = Image.new("RGBA", (width, height))
|
| 169 |
+
res.paste(resized, box=(width // 2 - src_w // 2, height // 2 - src_h // 2))
|
| 170 |
+
else:
|
| 171 |
+
ratio = width / height
|
| 172 |
+
src_ratio = im.width / im.height
|
| 173 |
+
|
| 174 |
+
src_w = width if ratio < src_ratio else im.width * height // im.height
|
| 175 |
+
src_h = height if ratio >= src_ratio else im.height * width // im.width
|
| 176 |
+
|
| 177 |
+
resized = im.resize((src_w, src_h), resample=LANCZOS)
|
| 178 |
+
res = Image.new("RGBA", (width, height))
|
| 179 |
+
res.paste(resized, box=(width // 2 - src_w // 2, height // 2 - src_h // 2))
|
| 180 |
+
|
| 181 |
+
if ratio < src_ratio:
|
| 182 |
+
fill_height = height // 2 - src_h // 2
|
| 183 |
+
res.paste(resized.resize((width, fill_height), box=(0, 0, width, 0)), box=(0, 0))
|
| 184 |
+
res.paste(resized.resize((width, fill_height), box=(0, resized.height, width, resized.height)), box=(0, fill_height + src_h))
|
| 185 |
+
elif ratio > src_ratio:
|
| 186 |
+
fill_width = width // 2 - src_w // 2
|
| 187 |
+
res.paste(resized.resize((fill_width, height), box=(0, 0, 0, height)), box=(0, 0))
|
| 188 |
+
res.paste(resized.resize((fill_width, height), box=(resized.width, 0, resized.width, height)), box=(fill_width + src_w, 0))
|
| 189 |
+
|
| 190 |
+
return res
|
| 191 |
+
|
| 192 |
+
def update_dimensions_info(width, height):
|
| 193 |
+
pixel_count_formated = "{:,.0f}".format(width * height)
|
| 194 |
+
return f"Aspect ratio: {round(width / height, 5)}\nTotal pixel count: {pixel_count_formated}"
|
| 195 |
+
|
| 196 |
+
def get_png_nfo( image: Image ):
|
| 197 |
+
info_text = ""
|
| 198 |
+
visible = bool(image and any(image.info))
|
| 199 |
+
if visible:
|
| 200 |
+
for key,value in image.info.items():
|
| 201 |
+
info_text += f"{key}: {value}\n"
|
| 202 |
+
info_text = info_text.rstrip('\n')
|
| 203 |
+
return gr.Textbox.update(value=info_text, visible=visible)
|
| 204 |
+
|
| 205 |
+
def load_settings(*values):
|
| 206 |
+
new_settings, key_names, checkboxgroup_info = values[-3:]
|
| 207 |
+
values = list(values[:-3])
|
| 208 |
+
|
| 209 |
+
if new_settings:
|
| 210 |
+
if type(new_settings) is str:
|
| 211 |
+
if os.path.exists(new_settings):
|
| 212 |
+
with open(new_settings, "r", encoding="utf8") as f:
|
| 213 |
+
new_settings = yaml.safe_load(f)
|
| 214 |
+
elif new_settings.startswith("file://") and os.path.exists(new_settings[7:]):
|
| 215 |
+
with open(new_settings[7:], "r", encoding="utf8") as f:
|
| 216 |
+
new_settings = yaml.safe_load(f)
|
| 217 |
+
else:
|
| 218 |
+
new_settings = yaml.safe_load(new_settings)
|
| 219 |
+
if type(new_settings) is not dict:
|
| 220 |
+
new_settings = {"prompt": new_settings}
|
| 221 |
+
if "txt2img" in new_settings:
|
| 222 |
+
new_settings = new_settings["txt2img"]
|
| 223 |
+
target = new_settings.pop("target", "txt2img")
|
| 224 |
+
if target != "txt2img":
|
| 225 |
+
print(f"Warning: applying settings to txt2img even though {target} is specified as target.", file=sys.stderr)
|
| 226 |
+
|
| 227 |
+
skipped_settings = {}
|
| 228 |
+
for key in new_settings.keys():
|
| 229 |
+
if key in key_names:
|
| 230 |
+
values[key_names.index(key)] = new_settings[key]
|
| 231 |
+
else:
|
| 232 |
+
skipped_settings[key] = new_settings[key]
|
| 233 |
+
if skipped_settings:
|
| 234 |
+
print(f"Settings could not be applied: {skipped_settings}", file=sys.stderr)
|
| 235 |
+
|
| 236 |
+
# Convert lists of checkbox indices to lists of checkbox labels:
|
| 237 |
+
for (cbg_index, cbg_choices) in checkboxgroup_info:
|
| 238 |
+
values[cbg_index] = [cbg_choices[i] for i in values[cbg_index]]
|
| 239 |
+
|
| 240 |
+
return values
|