diff --git a/.gitignore b/.gitignore
index f9c3357c..434d50b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,4 +27,5 @@ __pycache__
notification.mp3
/SwinIR
/textual_inversion
-.vscode
\ No newline at end of file
+.vscode
+/inspiration
\ No newline at end of file
diff --git a/javascript/imageviewer.js b/javascript/imageviewer.js
index 9e380c65..d4ab6984 100644
--- a/javascript/imageviewer.js
+++ b/javascript/imageviewer.js
@@ -116,7 +116,6 @@ function showGalleryImage() {
e.dataset.modded = true;
if(e && e.parentElement.tagName == 'DIV'){
e.style.cursor='pointer'
- e.style.userSelect='none'
e.addEventListener('click', function (evt) {
if(!opts.js_modal_lightbox) return;
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed)
diff --git a/javascript/inspiration.js b/javascript/inspiration.js
new file mode 100644
index 00000000..e1c0e114
--- /dev/null
+++ b/javascript/inspiration.js
@@ -0,0 +1,42 @@
+function public_image_index_in_gallery(item, gallery){
+ var index;
+ var i = 0;
+ gallery.querySelectorAll("img").forEach(function(e){
+ if (e == item)
+ index = i;
+ i += 1;
+ });
+ return index;
+}
+
+function inspiration_selected(name, types, name_list){
+ var btn = gradioApp().getElementById("inspiration_select_button")
+ return [gradioApp().getElementById("inspiration_select_button").getAttribute("img-index"), types];
+}
+var inspiration_image_click = function(){
+ var index = public_image_index_in_gallery(this, gradioApp().getElementById("inspiration_gallery"));
+ var btn = gradioApp().getElementById("inspiration_select_button")
+ btn.setAttribute("img-index", index)
+ setTimeout(function(btn){btn.click();}, 10, btn)
+}
+
+document.addEventListener("DOMContentLoaded", function() {
+ var mutationObserver = new MutationObserver(function(m){
+ var gallery = gradioApp().getElementById("inspiration_gallery")
+ if (gallery) {
+ var node = gallery.querySelector(".absolute.backdrop-blur.h-full")
+ if (node) {
+ node.style.display = "None"; //parentNode.removeChild(node)
+ }
+
+ gallery.querySelectorAll('img').forEach(function(e){
+ e.onclick = inspiration_image_click
+ })
+
+ }
+
+
+ });
+ mutationObserver.observe( gradioApp(), { childList:true, subtree:true });
+
+});
diff --git a/modules/inspiration.py b/modules/inspiration.py
new file mode 100644
index 00000000..456bfcb5
--- /dev/null
+++ b/modules/inspiration.py
@@ -0,0 +1,122 @@
+import os
+import random
+import gradio
+inspiration_path = "inspiration"
+inspiration_system_path = os.path.join(inspiration_path, "system")
+def read_name_list(file):
+ if not os.path.exists(file):
+ return []
+ f = open(file, "r")
+ ret = []
+ line = f.readline()
+ while len(line) > 0:
+ line = line.rstrip("\n")
+ ret.append(line)
+ print(ret)
+ return ret
+
+def save_name_list(file, name):
+ print(file)
+ f = open(file, "a")
+ f.write(name + "\n")
+
+def get_inspiration_images(source, types):
+ path = os.path.join(inspiration_path , types)
+ if source == "Favorites":
+ names = read_name_list(os.path.join(inspiration_system_path, types + "_faverites.txt"))
+ names = random.sample(names, 25)
+ elif source == "Abandoned":
+ names = read_name_list(os.path.join(inspiration_system_path, types + "_abondened.txt"))
+ names = random.sample(names, 25)
+ elif source == "Exclude abandoned":
+ abondened = read_name_list(os.path.join(inspiration_system_path, types + "_abondened.txt"))
+ all_names = os.listdir(path)
+ names = []
+ while len(names) < 25:
+ name = random.choice(all_names)
+ if name not in abondened:
+ names.append(name)
+ else:
+ names = random.sample(os.listdir(path), 25)
+ names = random.sample(names, 25)
+ image_list = []
+ for a in names:
+ image_path = os.path.join(path, a)
+ images = os.listdir(image_path)
+ image_list.append(os.path.join(image_path, random.choice(images)))
+ return image_list, names
+
+def select_click(index, types, name_list):
+ name = name_list[int(index)]
+ path = os.path.join(inspiration_path, types, name)
+ images = os.listdir(path)
+ return name, [os.path.join(path, x) for x in images]
+
+def give_up_click(name, types):
+ file = os.path.join(inspiration_system_path, types + "_abandoned.txt")
+ name_list = read_name_list(file)
+ if name not in name_list:
+ save_name_list(file, name)
+
+def collect_click(name, types):
+ file = os.path.join(inspiration_system_path, types + "_faverites.txt")
+ print(file)
+ name_list = read_name_list(file)
+ print(name_list)
+ if name not in name_list:
+ save_name_list(file, name)
+
+def moveout_click(name, types):
+ file = os.path.join(inspiration_system_path, types + "_faverites.txt")
+ name_list = read_name_list(file)
+ if name not in name_list:
+ save_name_list(file, name)
+
+def source_change(source):
+ if source == "Abandoned" or source == "Favorites":
+ return gradio.Button.update(visible=True, value=f"Move out {source}")
+ else:
+ return gradio.Button.update(visible=False)
+
+def ui(gr, opts):
+ with gr.Blocks(analytics_enabled=False) as inspiration:
+ flag = os.path.exists(inspiration_path)
+ if flag:
+ types = os.listdir(inspiration_path)
+ types = [x for x in types if x != "system"]
+ flag = len(types) > 0
+ if not flag:
+ os.mkdir(inspiration_path)
+ gr.HTML("""
+
"
+ """)
+ return inspiration
+ if not os.path.exists(inspiration_system_path):
+ os.mkdir(inspiration_system_path)
+ gallery, names = get_inspiration_images("Exclude abandoned", types[0])
+ with gr.Row():
+ with gr.Column(scale=2):
+ inspiration_gallery = gr.Gallery(gallery, show_label=False, elem_id="inspiration_gallery").style(grid=5, height='auto')
+ with gr.Column(scale=1):
+ types = gr.Dropdown(choices=types, value=types[0], label="Type", visible=len(types) > 1)
+ with gr.Row():
+ source = gr.Dropdown(choices=["All", "Favorites", "Exclude abandoned", "Abandoned"], value="Exclude abandoned", label="Source")
+ get_inspiration = gr.Button("Get inspiration")
+ name = gr.Textbox(show_label=False, interactive=False)
+ with gr.Row():
+ send_to_txt2img = gr.Button('to txt2img')
+ send_to_img2img = gr.Button('to img2img')
+ style_gallery = gr.Gallery(show_label=False, elem_id="inspiration_style_gallery").style(grid=2, height='auto')
+
+ collect = gr.Button('Collect')
+ give_up = gr.Button("Don't show any more")
+ moveout = gr.Button("Move out", visible=False)
+ with gr.Row():
+ select_button = gr.Button('set button', elem_id="inspiration_select_button")
+ name_list = gr.State(names)
+ source.change(source_change, inputs=[source], outputs=[moveout])
+ get_inspiration.click(get_inspiration_images, inputs=[source, types], outputs=[inspiration_gallery, name_list])
+ select_button.click(select_click, _js="inspiration_selected", inputs=[name, types, name_list], outputs=[name, style_gallery])
+ give_up.click(give_up_click, inputs=[name, types], outputs=None)
+ collect.click(collect_click, inputs=[name, types], outputs=None)
+ return inspiration
diff --git a/modules/shared.py b/modules/shared.py
index faede821..ae033710 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -78,6 +78,7 @@ parser.add_argument('--vae-path', type=str, help='Path to Variational Autoencode
parser.add_argument("--disable-safe-unpickle", action='store_true', help="disable checking pytorch models for malicious code", default=False)
parser.add_argument("--api", action='store_true', help="use api=True to launch the api with the webui")
parser.add_argument("--nowebui", action='store_true', help="use api=True to launch the api instead of the webui")
+parser.add_argument("--ui-debug-mode", action='store_true', help="Don't load model to quickly launch UI")
cmd_opts = parser.parse_args()
restricted_opts = [
diff --git a/modules/ui.py b/modules/ui.py
index a2dbd41e..6a0a3c3b 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -41,7 +41,8 @@ from modules import prompt_parser
from modules.images import save_image
import modules.textual_inversion.ui
import modules.hypernetworks.ui
-import modules.images_history as img_his
+import modules.images_history as images_history
+import modules.inspiration as inspiration
# this is a fix for Windows users. Without it, javascript files will be served with text/html content-type and the browser will not show any UI
mimetypes.init()
@@ -1082,9 +1083,9 @@ def create_ui(wrap_gradio_gpu_call):
upscaling_resize_w = gr.Number(label="Width", value=512, precision=0)
upscaling_resize_h = gr.Number(label="Height", value=512, precision=0)
upscaling_crop = gr.Checkbox(label='Crop to fit', value=True)
-
+
with gr.Group():
- extras_upscaler_1 = gr.Radio(label='Upscaler 1', elem_id="extras_upscaler_1", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name, type="index")
+ extras_upscaler_1 = gr.Radio(label='Upscaler 1', elem_id="extras_upscaler_1", choices=[x.name for x in shared.sd_upscalers] , value=shared.sd_upscalers[0].name, type="index")
with gr.Group():
extras_upscaler_2 = gr.Radio(label='Upscaler 2', elem_id="extras_upscaler_2", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name, type="index")
@@ -1178,7 +1179,8 @@ def create_ui(wrap_gradio_gpu_call):
"i2i":img2img_paste_fields
}
- images_history = img_his.create_history_tabs(gr, opts, wrap_gradio_call(modules.extras.run_pnginfo), images_history_switch_dict)
+ browser_interface = images_history.create_history_tabs(gr, opts, wrap_gradio_call(modules.extras.run_pnginfo), images_history_switch_dict)
+ inspiration_interface = inspiration.ui(gr, opts)
with gr.Blocks() as modelmerger_interface:
with gr.Row().style(equal_height=False):
@@ -1595,7 +1597,8 @@ Requested path was: {f}
(img2img_interface, "img2img", "img2img"),
(extras_interface, "Extras", "extras"),
(pnginfo_interface, "PNG Info", "pnginfo"),
- (images_history, "History", "images_history"),
+ (browser_interface, "History", "images_history"),
+ (inspiration_interface, "Inspiration", "inspiration"),
(modelmerger_interface, "Checkpoint Merger", "modelmerger"),
(train_interface, "Train", "ti"),
(settings_interface, "Settings", "settings"),
diff --git a/scripts/create_inspiration_images.py b/scripts/create_inspiration_images.py
new file mode 100644
index 00000000..6a20def8
--- /dev/null
+++ b/scripts/create_inspiration_images.py
@@ -0,0 +1,45 @@
+import csv, os, shutil
+import modules.scripts as scripts
+from modules import processing, shared, sd_samplers, images
+from modules.processing import Processed
+
+
+class Script(scripts.Script):
+ def title(self):
+ return "Create artists style image"
+
+ def show(self, is_img2img):
+ return not is_img2img
+
+ def ui(self, is_img2img):
+ return []
+ def show(self, is_img2img):
+ return not is_img2img
+
+ def run(self, p): #, max_snapshoots_num):
+ path = os.path.join("style_snapshoot", "artist")
+ if not os.path.exists(path):
+ os.makedirs(path)
+ p.do_not_save_samples = True
+ p.do_not_save_grid = True
+ p.negative_prompt = "portrait photo"
+ f = open('artists.csv')
+ f_csv = csv.reader(f)
+ for row in f_csv:
+ name = row[0]
+ artist_path = os.path.join(path, name)
+ if not os.path.exists(artist_path):
+ os.mkdir(artist_path)
+ if len(os.listdir(artist_path)) > 0:
+ continue
+ print(name)
+ p.prompt = name
+ processed = processing.process_images(p)
+ for img in processed.images:
+ i = 0
+ filename = os.path.join(artist_path, format(0, "03d") + ".jpg")
+ while os.path.exists(filename):
+ i += 1
+ filename = os.path.join(artist_path, format(i, "03d") + ".jpg")
+ img.save(filename, quality=70)
+ return processed
diff --git a/webui.py b/webui.py
index 177bef74..5923905f 100644
--- a/webui.py
+++ b/webui.py
@@ -72,6 +72,11 @@ def wrap_gradio_gpu_call(func, extra_outputs=None):
return modules.ui.wrap_gradio_call(f, extra_outputs=extra_outputs)
def initialize():
+ if cmd_opts.ui_debug_mode:
+ class enmpty():
+ name = None
+ shared.sd_upscalers = [enmpty()]
+ return
modelloader.cleanup_models()
modules.sd_models.setup_model()
codeformer.setup_model(cmd_opts.codeformer_models_path)