Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

geninfo from Infotexts #14645

Merged
merged 4 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions modules/infotext_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def restore_old_hires_fix_params(res):
res['Hires resize-2'] = height


def parse_generation_parameters(x: str):
def parse_generation_parameters(x: str, skip_fields: list[str] | None = None):
w-e-w marked this conversation as resolved.
Show resolved Hide resolved
"""parses generation parameters string, the one you see in text field under the picture in UI:
```
girl with an artist's beret, determined, blue eyes, desert scene, computer monitors, heavy makeup, by Alphonse Mucha and Charlie Bowater, ((eyeshadow)), (coquettish), detailed, intricate
Expand All @@ -240,6 +240,8 @@ def parse_generation_parameters(x: str):

returns a dict with field values
"""
if skip_fields is None:
skip_fields = shared.opts.infotext_skip_pasting
w-e-w marked this conversation as resolved.
Show resolved Hide resolved

res = {}

Expand Down Expand Up @@ -356,8 +358,8 @@ def parse_generation_parameters(x: str):

infotext_versions.backcompat(res)

skip = set(shared.opts.infotext_skip_pasting)
res = {k: v for k, v in res.items() if k not in skip}
for key in skip_fields:
res.pop(key, None)

return res

Expand Down
19 changes: 6 additions & 13 deletions modules/processing_scripts/seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from modules.infotext_utils import PasteField
from modules.shared import cmd_opts
from modules.ui_components import ToolButton
from modules import infotext_utils


class ScriptSeed(scripts.ScriptBuiltinUI):
Expand Down Expand Up @@ -77,29 +78,21 @@ def setup(self, p, seed, seed_checkbox, subseed, subseed_strength, seed_resize_f
p.seed_resize_from_h = seed_resize_from_h



def connect_reuse_seed(seed: gr.Number, reuse_seed: gr.Button, generation_info: gr.Textbox, is_subseed):
""" Connects a 'reuse (sub)seed' button's click event so that it copies last used
(sub)seed value from generation info the to the seed field. If copying subseed and subseed strength
was 0, i.e. no variation seed was used, it copies the normal seed value instead."""

def copy_seed(gen_info_string: str, index):
res = -1

try:
gen_info = json.loads(gen_info_string)
index -= gen_info.get('index_of_first_image', 0)

if is_subseed and gen_info.get('subseed_strength', 0) > 0:
all_subseeds = gen_info.get('all_subseeds', [-1])
res = all_subseeds[index if 0 <= index < len(all_subseeds) else 0]
else:
all_seeds = gen_info.get('all_seeds', [-1])
res = all_seeds[index if 0 <= index < len(all_seeds) else 0]

except json.decoder.JSONDecodeError:
infotext = gen_info.get('infotexts')[index]
gen_parameters = infotext_utils.parse_generation_parameters(infotext, [])
res = int(gen_parameters.get('Variation seed' if is_subseed else 'Seed', -1))
except Exception:
if gen_info_string:
errors.report(f"Error parsing JSON generation info: {gen_info_string}")
errors.report(f"Error retrieving seed from generation info: {gen_info_string}", exc_info=True)

return [res, gr.update()]

Expand Down
19 changes: 10 additions & 9 deletions modules/ui_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,24 @@ def save_files(js_data, images, do_make_zip, index):
import csv
filenames = []
fullfns = []
parsed_infotexts = []

#quick dictionary to class object conversion. Its necessary due apply_filename_pattern requiring it
# quick dictionary to class object conversion. Its necessary due apply_filename_pattern requiring it
class MyObject:
def __init__(self, d=None):
if d is not None:
for key, value in d.items():
setattr(self, key, value)

data = json.loads(js_data)

p = MyObject(data)

path = shared.opts.outdir_save
save_to_dirs = shared.opts.use_save_to_dirs_for_ui
extension: str = shared.opts.samples_format
start_index = 0
only_one = False

if index > -1 and shared.opts.save_selected_only and (index >= data["index_of_first_image"]): # ensures we are looking at a specific non-grid picture, and we have save_selected_only
only_one = True
images = [images[index]]
start_index = index

Expand All @@ -74,10 +73,12 @@ def __init__(self, d=None):
image = image_from_url_text(filedata)

is_grid = image_index < p.index_of_first_image
i = 0 if is_grid else (image_index - p.index_of_first_image)

p.batch_index = image_index-1
fullfn, txt_fullfn = modules.images.save_image(image, path, "", seed=p.all_seeds[i], prompt=p.all_prompts[i], extension=extension, info=p.infotexts[image_index], grid=is_grid, p=p, save_to_dirs=save_to_dirs)

parameters = parameters_copypaste.parse_generation_parameters(data["infotexts"][image_index], [])
parsed_infotexts.append(parameters)
fullfn, txt_fullfn = modules.images.save_image(image, path, "", seed=parameters['Seed'], prompt=parameters['Prompt'], extension=extension, info=p.infotexts[image_index], grid=is_grid, p=p, save_to_dirs=save_to_dirs)

filename = os.path.relpath(fullfn, path)
filenames.append(filename)
Expand All @@ -86,12 +87,12 @@ def __init__(self, d=None):
filenames.append(os.path.basename(txt_fullfn))
fullfns.append(txt_fullfn)

writer.writerow([data["prompt"], data["seed"], data["width"], data["height"], data["sampler_name"], data["cfg_scale"], data["steps"], filenames[0], data["negative_prompt"]])
writer.writerow([parsed_infotexts[0]['Prompt'], parsed_infotexts[0]['Seed'], data["width"], data["height"], data["sampler_name"], data["cfg_scale"], data["steps"], filenames[0], parsed_infotexts[0]['Negative prompt']])

# Make Zip
if do_make_zip:
zip_fileseed = p.all_seeds[index-1] if only_one else p.all_seeds[0]
namegen = modules.images.FilenameGenerator(p, zip_fileseed, p.all_prompts[0], image, True)
p.all_seeds = [parameters['Seed'] for parameters in parsed_infotexts]
namegen = modules.images.FilenameGenerator(p, parsed_infotexts[0]['Seed'], parsed_infotexts[0]['Prompt'], image, True)
zip_filename = namegen.apply(shared.opts.grid_zip_filename_pattern or "[datetime]_[[model_name]]_[seed]-[seed_last]")
zip_filepath = os.path.join(path, f"{zip_filename}.zip")

Expand Down