Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…sion-webui into 0318
  • Loading branch information
xieyongliang committed Mar 21, 2023
2 parents 59f91bd + 5447455 commit 8dc1030
Show file tree
Hide file tree
Showing 8 changed files with 830 additions and 10 deletions.
1 change: 1 addition & 0 deletions localizations/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"Prompt matrix": "提示词矩阵",
"Prompts from file or textbox": "从文本框或文件载入提示词",
"X/Y plot": "X/Y 图表",
"X/Y/Z plot": "X/Y/Z 图表",
"Source embedding to convert": "用于转换的源 Embedding",
"Embedding token": "Embedding 的 token (关键词)",
"Output directory": "输出目录",
Expand Down
15 changes: 9 additions & 6 deletions modules/generation_parameters_copypaste.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
import io
import os
import re
from pathlib import Path

import gradio as gr
from modules.shared import script_path
from modules import shared
import tempfile
from modules import shared, ui_tempdir
from PIL import Image

re_param_code = r'\s*([\w ]+):\s*("(?:\\|\"|[^\"])+"|[^,]*)(?:,|$)'
Expand Down Expand Up @@ -35,9 +33,15 @@ def quote(text):


def image_from_url_text(filedata):
if type(filedata) == dict and filedata["is_file"]:
if filedata is None:
return None

if type(filedata) == list and len(filedata) > 0 and type(filedata[0]) == dict and filedata[0].get("is_file", False):
filedata = filedata[0]

if type(filedata) == dict and filedata.get("is_file", False):
filename = filedata["name"]
is_in_right_dir = any(Path(temp_dir).resolve() in Path(filename).resolve().parents for temp_dir in shared.demo.temp_dirs)
is_in_right_dir = ui_tempdir.check_tmp_file(shared.demo, filename)
assert is_in_right_dir, 'trying to open image file outside of allowed directories'

return Image.open(filename)
Expand All @@ -55,7 +59,6 @@ def image_from_url_text(filedata):
image = Image.open(io.BytesIO(filedata))
return image


def add_paste_fields(tabname, init_img, fields):
paste_fields[tabname] = {"init_img": init_img, "fields": fields}

Expand Down
92 changes: 91 additions & 1 deletion modules/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,98 @@ def __init__(self, text='', is_active=True):
self.is_active = is_active
self.size = None

def draw_grid_annotations(im, width, height, hor_texts, ver_texts, margin=0):
def wrap(drawing, text, font, line_length):
lines = ['']
for word in text.split():
line = f'{lines[-1]} {word}'.strip()
if drawing.textlength(line, font=font) <= line_length:
lines[-1] = line
else:
lines.append(word)
return lines

def get_font(fontsize):
try:
return ImageFont.truetype(opts.font or Roboto, fontsize)
except Exception:
return ImageFont.truetype(Roboto, fontsize)

def draw_texts(drawing, draw_x, draw_y, lines, initial_fnt, initial_fontsize):
for i, line in enumerate(lines):
fnt = initial_fnt
fontsize = initial_fontsize
while drawing.multiline_textsize(line.text, font=fnt)[0] > line.allowed_width and fontsize > 0:
fontsize -= 1
fnt = get_font(fontsize)
drawing.multiline_text((draw_x, draw_y + line.size[1] / 2), line.text, font=fnt, fill=color_active if line.is_active else color_inactive, anchor="mm", align="center")

if not line.is_active:
drawing.line((draw_x - line.size[0] // 2, draw_y + line.size[1] // 2, draw_x + line.size[0] // 2, draw_y + line.size[1] // 2), fill=color_inactive, width=4)

draw_y += line.size[1] + line_spacing

fontsize = (width + height) // 25
line_spacing = fontsize // 2

fnt = get_font(fontsize)

color_active = (0, 0, 0)
color_inactive = (153, 153, 153)

pad_left = 0 if sum([sum([len(line.text) for line in lines]) for lines in ver_texts]) == 0 else width * 3 // 4

cols = im.width // width
rows = im.height // height

assert cols == len(hor_texts), f'bad number of horizontal texts: {len(hor_texts)}; must be {cols}'
assert rows == len(ver_texts), f'bad number of vertical texts: {len(ver_texts)}; must be {rows}'

calc_img = Image.new("RGB", (1, 1), "white")
calc_d = ImageDraw.Draw(calc_img)

for texts, allowed_width in zip(hor_texts + ver_texts, [width] * len(hor_texts) + [pad_left] * len(ver_texts)):
items = [] + texts
texts.clear()

for line in items:
wrapped = wrap(calc_d, line.text, fnt, allowed_width)
texts += [GridAnnotation(x, line.is_active) for x in wrapped]

for line in texts:
bbox = calc_d.multiline_textbbox((0, 0), line.text, font=fnt)
line.size = (bbox[2] - bbox[0], bbox[3] - bbox[1])
line.allowed_width = allowed_width

hor_text_heights = [sum([line.size[1] + line_spacing for line in lines]) - line_spacing for lines in hor_texts]
ver_text_heights = [sum([line.size[1] + line_spacing for line in lines]) - line_spacing * len(lines) for lines in ver_texts]

pad_top = 0 if sum(hor_text_heights) == 0 else max(hor_text_heights) + line_spacing * 2

result = Image.new("RGB", (im.width + pad_left + margin * (cols-1), im.height + pad_top + margin * (rows-1)), "white")

for row in range(rows):
for col in range(cols):
cell = im.crop((width * col, height * row, width * (col+1), height * (row+1)))
result.paste(cell, (pad_left + (width + margin) * col, pad_top + (height + margin) * row))

d = ImageDraw.Draw(result)

for col in range(cols):
x = pad_left + (width + margin) * col + width / 2
y = pad_top / 2 - hor_text_heights[col] / 2

draw_texts(d, x, y, hor_texts[col], fnt, fontsize)

for row in range(rows):
x = pad_left / 2
y = pad_top + (height + margin) * row + height / 2 - ver_text_heights[row] / 2

draw_texts(d, x, y, ver_texts[row], fnt, fontsize)

return result

def draw_grid_annotations(im, width, height, hor_texts, ver_texts):
def draw_grid_annotations_old(im, width, height, hor_texts, ver_texts):
def wrap(drawing, text, font, line_length):
lines = ['']
for word in text.split():
Expand Down
9 changes: 9 additions & 0 deletions modules/scripts.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import sys
import traceback
import re
from collections import namedtuple

import gradio as gr
Expand Down Expand Up @@ -116,7 +117,15 @@ def after_component(self, component, **kwargs):
def describe(self):
"""unused"""
return ""

def elem_id(self, item_id):
"""helper function to generate id for a HTML element, constructs final id out of script name, tab and user-supplied item_id"""

need_tabname = self.show(True) == self.show(False)
tabname = ('img2img' if self.is_img2img else 'txt2txt') + "_" if need_tabname else ""
title = re.sub(r'[^a-z_0-9]', '', re.sub(r'\s', '_', self.title().lower()))

return f'script_{tabname}{title}_{item_id}'

current_basedir = paths.script_path

Expand Down
58 changes: 58 additions & 0 deletions modules/ui_components.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import gradio as gr


class ToolButton(gr.Button, gr.components.FormComponent):
"""Small button with single emoji as text, fits inside gradio forms"""

def __init__(self, **kwargs):
super().__init__(variant="tool", **kwargs)

def get_block_name(self):
return "button"


class ToolButtonTop(gr.Button, gr.components.FormComponent):
"""Small button with single emoji as text, with extra margin at top, fits inside gradio forms"""

def __init__(self, **kwargs):
super().__init__(variant="tool-top", **kwargs)

def get_block_name(self):
return "button"


class FormRow(gr.Row, gr.components.FormComponent):
"""Same as gr.Row but fits inside gradio forms"""

def get_block_name(self):
return "row"


class FormGroup(gr.Group, gr.components.FormComponent):
"""Same as gr.Row but fits inside gradio forms"""

def get_block_name(self):
return "group"


class FormHTML(gr.HTML, gr.components.FormComponent):
"""Same as gr.HTML but fits inside gradio forms"""

def get_block_name(self):
return "html"


class FormColorPicker(gr.ColorPicker, gr.components.FormComponent):
"""Same as gr.ColorPicker but fits inside gradio forms"""

def get_block_name(self):
return "colorpicker"


class DropdownMulti(gr.Dropdown):
"""Same as gr.Dropdown but always multiselect"""
def __init__(self, **kwargs):
super().__init__(multiselect=True, **kwargs)

def get_block_name(self):
return "dropdown"
24 changes: 22 additions & 2 deletions modules/ui_tempdir.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import tempfile
from collections import namedtuple
from pathlib import Path

import gradio as gr

Expand All @@ -12,10 +13,29 @@
Savedfile = namedtuple("Savedfile", ["name"])


def register_tmp_file(gradio, filename):
if hasattr(gradio, 'temp_file_sets'): # gradio 3.15
gradio.temp_file_sets[0] = gradio.temp_file_sets[0] | {os.path.abspath(filename)}

if hasattr(gradio, 'temp_dirs'): # gradio 3.9
gradio.temp_dirs = gradio.temp_dirs | {os.path.abspath(os.path.dirname(filename))}


def check_tmp_file(gradio, filename):
if hasattr(gradio, 'temp_file_sets'):
return any([filename in fileset for fileset in gradio.temp_file_sets])

if hasattr(gradio, 'temp_dirs'):
return any(Path(temp_dir).resolve() in Path(filename).resolve().parents for temp_dir in gradio.temp_dirs)

return False


def save_pil_to_file(pil_image, dir=None):
already_saved_as = getattr(pil_image, 'already_saved_as', None)
if already_saved_as and os.path.isfile(already_saved_as):
shared.demo.temp_dirs = shared.demo.temp_dirs | {os.path.abspath(os.path.dirname(already_saved_as))}
register_tmp_file(shared.demo, already_saved_as)

file_obj = Savedfile(already_saved_as)
return file_obj

Expand Down Expand Up @@ -44,7 +64,7 @@ def on_tmpdir_changed():

os.makedirs(shared.opts.temp_dir, exist_ok=True)

shared.demo.temp_dirs = shared.demo.temp_dirs | {os.path.abspath(shared.opts.temp_dir)}
register_tmp_file(shared.demo, os.path.join(shared.opts.temp_dir, "x"))


def cleanup_tmpdr():
Expand Down
Loading

0 comments on commit 8dc1030

Please sign in to comment.