| | import re |
| | import gradio as gr |
| | from PIL import Image, ImageFont, ImageDraw, ImageFilter, ImageOps |
| | from io import BytesIO |
| | import base64 |
| | import re |
| |
|
| | def change_img_choices(sample_size): |
| | choices = [] |
| | for i in range(int(sample_size)): |
| | choices.append( |
| | '图片{}(img{})'.format(i+1,i+1) |
| | ) |
| | update_choices = gr.update(choices=choices) |
| | return update_choices |
| |
|
| | def change_image_editor_mode(choice, cropped_image, masked_image, resize_mode, width, height): |
| | if choice == "Mask": |
| | update_image_result = update_image_mask(cropped_image, resize_mode, width, height) |
| | 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)] |
| |
|
| | update_image_result = update_image_mask(masked_image["image"] if masked_image is not None else None, resize_mode, width, height) |
| | 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)] |
| |
|
| | def update_image_mask(cropped_image, resize_mode, width, height): |
| | resized_cropped_image = resize_image(resize_mode, cropped_image, width, height) if cropped_image else None |
| | return gr.update(value=resized_cropped_image, visible=True) |
| |
|
| | def toggle_options_gfpgan(selection): |
| | if 0 in selection: |
| | return gr.update(visible=True) |
| | else: |
| | return gr.update(visible=False) |
| |
|
| | def toggle_options_upscalers(selection): |
| | if 1 in selection: |
| | return gr.update(visible=True) |
| | else: |
| | return gr.update(visible=False) |
| |
|
| | def toggle_options_realesrgan(selection): |
| | if selection == 0 or selection == 1 or selection == 3: |
| | return gr.update(visible=True) |
| | else: |
| | return gr.update(visible=False) |
| |
|
| | def toggle_options_gobig(selection): |
| | if selection == 1: |
| | |
| | return gr.update(visible=True) |
| | if selection == 3: |
| | return gr.update(visible=True) |
| | else: |
| | return gr.update(visible=False) |
| |
|
| | def toggle_options_ldsr(selection): |
| | if selection == 2 or selection == 3: |
| | return gr.update(visible=True) |
| | else: |
| | return gr.update(visible=False) |
| |
|
| | def increment_down(value): |
| | return value - 1 |
| |
|
| | def increment_up(value): |
| | return value + 1 |
| |
|
| | def copy_img_to_lab(img): |
| | try: |
| | image_data = re.sub('^data:image/.+;base64,', '', img) |
| | processed_image = Image.open(BytesIO(base64.b64decode(image_data))) |
| | tab_update = gr.update(selected='imgproc_tab') |
| | img_update = gr.update(value=processed_image) |
| | return processed_image, tab_update, |
| | except IndexError: |
| | return [None, None] |
| | def copy_img_params_to_lab(params): |
| | try: |
| | prompt = params[0][0].replace('\n', ' ').replace('\r', '') |
| | seed = int(params[1][1]) |
| | steps = int(params[7][1]) |
| | cfg_scale = float(params[9][1]) |
| | sampler = params[11][1] |
| | return prompt,seed,steps,cfg_scale,sampler |
| | except IndexError: |
| | return [None, None] |
| | def copy_img_to_input(img, idx): |
| | try: |
| | |
| | |
| | |
| | idx_map = { |
| | "图片1(img1)":0, |
| | "图片2(img2)":1, |
| | "图片3(img3)":2, |
| | "图片4(img4)":3, |
| | } |
| | idx = idx_map[idx] |
| | image_data = re.sub('^data:image/.+;base64,', '', img[idx]) |
| | processed_image = Image.open(BytesIO(base64.b64decode(image_data))) |
| | tab_update = gr.update(selected='img2img_tab') |
| | img_update = gr.update(value=processed_image) |
| | move_prompt_zh_update = gr.update(visible=True) |
| | move_prompt_en_update = gr.update(visible=True) |
| | prompt_update = gr.update(visible=True) |
| | return tab_update,processed_image, processed_image, move_prompt_zh_update, move_prompt_en_update, prompt_update |
| | except IndexError: |
| | return [None, None] |
| |
|
| | def copy_img_to_edit(img): |
| | try: |
| | image_data = re.sub('^data:image/.+;base64,', '', img) |
| | processed_image = Image.open(BytesIO(base64.b64decode(image_data))) |
| | tab_update = gr.update(selected='img2img_tab') |
| | img_update = gr.update(value=processed_image) |
| | mode_update = gr.update(value='Crop') |
| | return processed_image, tab_update, mode_update |
| | except IndexError: |
| | return [None, None] |
| |
|
| | def copy_img_to_mask(img): |
| | try: |
| | image_data = re.sub('^data:image/.+;base64,', '', img) |
| | processed_image = Image.open(BytesIO(base64.b64decode(image_data))) |
| | tab_update = gr.update(selected='img2img_tab') |
| | img_update = gr.update(value=processed_image) |
| | mode_update = gr.update(value='Mask') |
| | return processed_image, tab_update, mode_update |
| | except IndexError: |
| | return [None, None] |
| |
|
| |
|
| |
|
| | def copy_img_to_upscale_esrgan(img): |
| | tabs_update = gr.update(selected='realesrgan_tab') |
| | image_data = re.sub('^data:image/.+;base64,', '', img) |
| | processed_image = Image.open(BytesIO(base64.b64decode(image_data))) |
| | return processed_image, tabs_update |
| |
|
| |
|
| | help_text = """ |
| | ## Mask/Crop |
| | * Masking is not inpainting. You will probably get better results manually masking your images in photoshop instead. |
| | * Built-in masking/cropping is very temperamental. |
| | * It may take some time for the image to show when switching from Crop to Mask. |
| | * If the image doesn't appear after switching to Mask, switch back to Crop and then back again to Mask |
| | * If the mask appears distorted (the brush is weirdly shaped instead of round), switch back to Crop and then back again to Mask. |
| | |
| | ## Advanced Editor |
| | * Click 💾 Save to send your editor changes to the img2img workflow |
| | * Click ❌ Clear to discard your editor changes |
| | |
| | If anything breaks, try switching modes again, switch tabs, clear the image, or reload. |
| | """ |
| |
|
| | def resize_image(resize_mode, im, width, height): |
| | LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS) |
| | if resize_mode == 0: |
| | res = im.resize((width, height), resample=LANCZOS) |
| | elif resize_mode == 1: |
| | ratio = width / height |
| | src_ratio = im.width / im.height |
| |
|
| | src_w = width if ratio > src_ratio else im.width * height // im.height |
| | src_h = height if ratio <= src_ratio else im.height * width // im.width |
| |
|
| | resized = im.resize((src_w, src_h), resample=LANCZOS) |
| | res = Image.new("RGBA", (width, height)) |
| | res.paste(resized, box=(width // 2 - src_w // 2, height // 2 - src_h // 2)) |
| | else: |
| | ratio = width / height |
| | src_ratio = im.width / im.height |
| |
|
| | src_w = width if ratio < src_ratio else im.width * height // im.height |
| | src_h = height if ratio >= src_ratio else im.height * width // im.width |
| |
|
| | resized = im.resize((src_w, src_h), resample=LANCZOS) |
| | res = Image.new("RGBA", (width, height)) |
| | res.paste(resized, box=(width // 2 - src_w // 2, height // 2 - src_h // 2)) |
| |
|
| | if ratio < src_ratio: |
| | fill_height = height // 2 - src_h // 2 |
| | res.paste(resized.resize((width, fill_height), box=(0, 0, width, 0)), box=(0, 0)) |
| | res.paste(resized.resize((width, fill_height), box=(0, resized.height, width, resized.height)), box=(0, fill_height + src_h)) |
| | elif ratio > src_ratio: |
| | fill_width = width // 2 - src_w // 2 |
| | res.paste(resized.resize((fill_width, height), box=(0, 0, 0, height)), box=(0, 0)) |
| | res.paste(resized.resize((fill_width, height), box=(resized.width, 0, resized.width, height)), box=(fill_width + src_w, 0)) |
| |
|
| | return res |
| |
|
| | def update_dimensions_info(width, height): |
| | pixel_count_formated = "{:,.0f}".format(width * height) |
| | return f"Aspect ratio: {round(width / height, 5)}\nTotal pixel count: {pixel_count_formated}" |
| |
|
| | def get_png_nfo( image: Image ): |
| | info_text = "" |
| | visible = bool(image and any(image.info)) |
| | if visible: |
| | for key,value in image.info.items(): |
| | info_text += f"{key}: {value}\n" |
| | info_text = info_text.rstrip('\n') |
| | return gr.Textbox.update(value=info_text, visible=visible) |
| |
|
| | def load_settings(*values): |
| | new_settings, key_names, checkboxgroup_info = values[-3:] |
| | values = list(values[:-3]) |
| |
|
| | if new_settings: |
| | if type(new_settings) is str: |
| | if os.path.exists(new_settings): |
| | with open(new_settings, "r", encoding="utf8") as f: |
| | new_settings = yaml.safe_load(f) |
| | elif new_settings.startswith("file://") and os.path.exists(new_settings[7:]): |
| | with open(new_settings[7:], "r", encoding="utf8") as f: |
| | new_settings = yaml.safe_load(f) |
| | else: |
| | new_settings = yaml.safe_load(new_settings) |
| | if type(new_settings) is not dict: |
| | new_settings = {"prompt": new_settings} |
| | if "txt2img" in new_settings: |
| | new_settings = new_settings["txt2img"] |
| | target = new_settings.pop("target", "txt2img") |
| | if target != "txt2img": |
| | print(f"Warning: applying settings to txt2img even though {target} is specified as target.", file=sys.stderr) |
| |
|
| | skipped_settings = {} |
| | for key in new_settings.keys(): |
| | if key in key_names: |
| | values[key_names.index(key)] = new_settings[key] |
| | else: |
| | skipped_settings[key] = new_settings[key] |
| | if skipped_settings: |
| | print(f"Settings could not be applied: {skipped_settings}", file=sys.stderr) |
| |
|
| | |
| | for (cbg_index, cbg_choices) in checkboxgroup_info: |
| | values[cbg_index] = [cbg_choices[i] for i in values[cbg_index]] |
| |
|
| | return values |
| |
|