initial built-in styles

This commit is contained in:
Vladimir Mandic
2023-10-04 16:06:02 -04:00
parent 195c662864
commit 1369c4d714
6 changed files with 2066 additions and 58 deletions
+4 -1
View File
@@ -7,7 +7,8 @@
- Add FreeU for *backend:diffusers*
for *backend:original* use extension: <https://github.com/ljleb/sd-webui-freeu>
- Add HyperTile: <https://github.com/tfernd/HyperTile>
- Implement Styles extra field
- Implement styles extra field
- Add built-in styles
This is a big one, with some major changes and new functionality...
And probably the biggest release since introduction of **Diffusers**
@@ -40,6 +41,8 @@ Upgrades are still possible and supported, but above is recommended for best exp
- can be edited in details view
- support for single or multiple styles per json
- support for embedded previews
- large database of art styles included by default
can be disabled in *settings -> extra networks -> show built-in*
- **VAE**
- VAEs are now also listed as part of extra networks
- **Refiner**
+2018
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -671,6 +671,7 @@ options_templates.update(options_section(('interrogate', "Interrogate"), {
options_templates.update(options_section(('extra_networks', "Extra Networks"), {
"extra_networks": OptionInfo(["All"], "Extra networks", ui_components.DropdownMulti, lambda: {"choices": ['All'] + [en.title for en in extra_networks]}),
"extra_networks_styles": OptionInfo(True, "Show built-in styles"),
"extra_networks_card_cover": OptionInfo("sidebar", "UI position", gr.Radio, lambda: {"choices": ["cover", "inline", "sidebar"]}),
"extra_networks_height": OptionInfo(53, "UI height (%)", gr.Slider, {"minimum": 10, "maximum": 100, "step": 1}),
"extra_networks_sidebar_width": OptionInfo(35, "UI sidebar width (%)", gr.Slider, {"minimum": 10, "maximum": 80, "step": 1}),
+33 -22
View File
@@ -43,6 +43,7 @@ class StyleDatabase:
self.no_style = Style("None")
self.styles = {}
self.path = opts.styles_dir
self.built_in = opts.extra_networks_styles
if os.path.isfile(opts.styles_dir) or opts.styles_dir.endswith(".csv"):
legacy_file = opts.styles_dir
self.load_csv(legacy_file)
@@ -57,39 +58,49 @@ class StyleDatabase:
self.path = opts.styles_dir
os.makedirs(opts.styles_dir, exist_ok=True)
def load_style(self, fn, prefix=None):
with open(fn, 'r', encoding='utf-8') as f:
try:
all_styles = json.load(f)
if type(all_styles) is dict:
all_styles = [all_styles]
for style in all_styles:
if type(style) is not dict or "name" not in style:
raise ValueError('cannot parse style')
basename = os.path.splitext(os.path.basename(fn))[0]
name = re.sub(r'[\t\r\n]', '', style.get("name", basename)).strip()
if prefix is not None:
name = os.path.join(prefix, name)
else:
name = os.path.join(os.path.dirname(os.path.relpath(fn, self.path)), name)
self.styles[style["name"]] = Style(
name=name,
desc=style.get('description', name),
prompt=style.get("prompt", ""),
negative_prompt=style.get("negative", ""),
extra=style.get("extra", ""),
preview=style.get("preview", None),
filename=fn
)
except Exception as e:
log.error(f'Failed to load style: file={fn} error={e}')
def reload(self):
self.styles.clear()
def list_folder(folder):
for filename in os.listdir(folder):
fn = os.path.abspath(os.path.join(folder, filename))
if os.path.isfile(fn) and fn.lower().endswith(".json"):
with open(fn, 'r', encoding='utf-8') as f:
try:
all_styles = json.load(f)
if type(all_styles) is dict:
all_styles = [all_styles]
for style in all_styles:
if type(style) is not dict or "name" not in style:
raise ValueError('cannot parse style')
basename = os.path.splitext(os.path.basename(fn))[0]
name = re.sub(r'[\t\r\n]', '', style.get("name", basename)).strip()
name = os.path.join(os.path.dirname(os.path.relpath(fn, self.path)), name)
self.styles[style["name"]] = Style(
name=name,
desc=style.get('description', name),
prompt=style.get("prompt", ""),
negative_prompt=style.get("negative", ""),
extra=style.get("extra", ""),
preview=style.get("preview", None),
filename=fn
)
except Exception as e:
log.error(f'Failed to load style: file={fn} error={e}')
self.load_style(fn)
elif os.path.isdir(fn) and not fn.startswith('.'):
list_folder(fn)
list_folder(self.path)
self.styles = dict(sorted(self.styles.items(), key=lambda style: style[1].filename))
if self.built_in:
self.load_style(os.path.join(paths.data_path, 'html', 'art-styles.json'), 'built-in')
log.debug(f'Loaded styles: folder={self.path} items={len(self.styles.keys())}')
def find_style(self, name):
+9 -1
View File
@@ -1,7 +1,9 @@
import io
import re
import time
import json
import html
import base64
import os.path
import urllib.parse
import threading
@@ -228,6 +230,8 @@ class ExtraNetworksPage:
if not self.is_empty(tgt):
subdirs[subdir] = 1
subdirs = OrderedDict(sorted(subdirs.items()))
if self.name == 'style' and shared.opts.extra_networks_styles:
subdirs['built-in'] = 1
subdirs_html = "<button class='lg secondary gradio-button custom-button search-all' onclick='extraNetworksSearchButton(event)'>all</button><br>"
subdirs_html += "".join([f"<button class='lg secondary gradio-button custom-button' onclick='extraNetworksSearchButton(event)'>{html.escape(subdir)}</button><br>" for subdir in subdirs if subdir != ''])
self.html = ''
@@ -586,7 +590,11 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
meta = json.loads(meta)
except Exception:
meta = {}
img = page.find_preview_file(item.filename)
if ui.last_item.preview.startswith('data:'):
b64str = ui.last_item.preview.split(',',1)[1]
img = Image.open(io.BytesIO(base64.b64decode(b64str)))
else:
img = page.find_preview_file(item.filename)
lora = ''
model = ''
style = ''
+1 -34
View File
@@ -11,39 +11,6 @@ class ExtraNetworksPageStyles(ui_extra_networks.ExtraNetworksPage):
def refresh(self):
shared.prompt_styles.reload()
"""
import io
import base64
from PIL import Image
def image2str(image):
buff = io.BytesIO()
image.save(buff, format="JPEG", quality=80)
encoded = base64.b64encode(buff.getvalue())
return encoded
def str2image(data):
buff = io.BytesIO(base64.b64decode(data))
return Image.open(buff)
def save_preview(self, index, images, filename):
from modules.generation_parameters_copypaste import image_from_url_text
try:
image = image_from_url_text(images[int(index)])
except Exception:
shared.log.error(f'Extra network save preview: {filename} no image')
return
if image.width > 512 or image.height > 512:
image = image.convert('RGB').thumbnail((512, 512), Image.HAMMING)
for k in shared.prompt_styles.styles.keys():
if k == filename:
shared.prompt_styles.styles[k].preview = image2str(image)
break
def save_description(self, filename, desc):
pass
"""
def parse_desc(self, desc):
lines = desc.strip().split("\n")
params = { 'name': '', 'description': '', 'prompt': '', 'negative': '', 'extra': ''}
@@ -124,4 +91,4 @@ class ExtraNetworksPageStyles(ui_extra_networks.ExtraNetworksPage):
def allowed_directories_for_previews(self):
return [v for v in [shared.opts.styles_dir] if v is not None]
return [v for v in [shared.opts.styles_dir] if v is not None] + ['html']