Skip to content

Commit d7263b3

Browse files
authored
Merge pull request #78 from v8hid/develop
v1.2 Added common prompt prefix and suffix for better user experience. Improved frame correction and enhancement with mask_blur and non-inpainting models. All main frames will be shown as a gallery view in output. Updated default parameter values. Fixed bugs related to prompts import. Made improvements to UI parameter Names and Frame problem (It's gone). Refactored code for better maintenance.
2 parents 28a1a0f + aecab9c commit d7263b3

16 files changed

+1373
-936
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,4 @@ dmypy.json
129129
.pyre/
130130
.vscode/settings.json
131131
.DS_Store
132+
/.vs

iz_helpers/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
from .image import shrink_and_paste_on_blank
2-
from .video import write_video
1+
# from .ui import on_ui_tabs
2+
# from .settings import on_ui_settings

iz_helpers/extra.py

Whitespace-only changes.

iz_helpers/helpers.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import math
2+
import os
3+
import modules.shared as shared
4+
import modules.sd_models
5+
import gradio as gr
6+
from scripts import postprocessing_upscale
7+
from .prompt_util import readJsonPrompt
8+
import asyncio
9+
10+
11+
def fix_env_Path_ffprobe():
12+
envpath = os.environ["PATH"]
13+
ffppath = shared.opts.data.get("infzoom_ffprobepath", "")
14+
15+
if ffppath and not ffppath in envpath:
16+
path_sep = ";" if os.name == "nt" else ":"
17+
os.environ["PATH"] = envpath + path_sep + ffppath
18+
19+
20+
def closest_upper_divisible_by_eight(num):
21+
if num % 8 == 0:
22+
return num
23+
else:
24+
return math.ceil(num / 8) * 8
25+
26+
27+
def load_model_from_setting(model_field_name, progress, progress_desc):
28+
# fix typo in Automatic1111 vs Vlad111
29+
if hasattr(modules.sd_models, "checkpoint_alisases"):
30+
checkPList = modules.sd_models.checkpoint_alisases
31+
elif hasattr(modules.sd_models, "checkpoint_aliases"):
32+
checkPList = modules.sd_models.checkpoint_aliases
33+
else:
34+
raise Exception(
35+
"This is not a compatible StableDiffusion Platform, can not access checkpoints"
36+
)
37+
38+
model_name = shared.opts.data.get(model_field_name)
39+
if model_name is not None and model_name != "":
40+
checkinfo = checkPList[model_name]
41+
42+
if not checkinfo:
43+
raise NameError(model_field_name + " Does not exist in your models.")
44+
45+
if progress:
46+
progress(0, desc=progress_desc + checkinfo.name)
47+
48+
modules.sd_models.load_model(checkinfo)
49+
50+
51+
def do_upscaleImg(curImg, upscale_do, upscaler_name, upscale_by):
52+
if not upscale_do:
53+
return curImg
54+
55+
# ensure even width and even height for ffmpeg
56+
# if odd, switch to scale to mode
57+
rwidth = round(curImg.width * upscale_by)
58+
rheight = round(curImg.height * upscale_by)
59+
60+
ups_mode = 2 # upscale_by
61+
if (rwidth % 2) == 1:
62+
ups_mode = 1
63+
rwidth += 1
64+
if (rheight % 2) == 1:
65+
ups_mode = 1
66+
rheight += 1
67+
68+
if 1 == ups_mode:
69+
print(
70+
"Infinite Zoom: aligning output size to even width and height: "
71+
+ str(rwidth)
72+
+ " x "
73+
+ str(rheight),
74+
end="\r",
75+
)
76+
77+
pp = postprocessing_upscale.scripts_postprocessing.PostprocessedImage(curImg)
78+
ups = postprocessing_upscale.ScriptPostprocessingUpscale()
79+
ups.process(
80+
pp,
81+
upscale_mode=ups_mode,
82+
upscale_by=upscale_by,
83+
upscale_to_width=rwidth,
84+
upscale_to_height=rheight,
85+
upscale_crop=False,
86+
upscaler_1_name=upscaler_name,
87+
upscaler_2_name=None,
88+
upscaler_2_visibility=0.0,
89+
)
90+
return pp.image
91+
92+
async def showGradioErrorAsync(txt, delay=1):
93+
await asyncio.sleep(delay) # sleep for 1 second
94+
raise gr.Error(txt)
95+
96+
def putPrompts(files):
97+
try:
98+
with open(files.name, "r") as f:
99+
file_contents = f.read()
100+
101+
data = readJsonPrompt(file_contents,False)
102+
return [
103+
gr.Textbox.update(data["prePrompt"]),
104+
gr.DataFrame.update(data["prompts"]),
105+
gr.Textbox.update(data["postPrompt"]),
106+
gr.Textbox.update(data["negPrompt"])
107+
]
108+
109+
except Exception:
110+
print(
111+
"[InfiniteZoom:] Loading your prompt failed. It seems to be invalid. Your prompt table is preserved."
112+
)
113+
114+
# error only be shown with raise, so ui gets broken.
115+
#asyncio.run(showGradioErrorAsync("Loading your prompts failed. It seems to be invalid. Your prompt table has been preserved.",5))
116+
117+
return [gr.Textbox.update(), gr.DataFrame.update(), gr.Textbox.update(),gr.Textbox.update()]
118+
119+
120+
def clearPrompts():
121+
return [
122+
gr.DataFrame.update(value=[[0, "Infinite Zoom. Start over"]]),
123+
gr.Textbox.update(""),
124+
gr.Textbox.update(""),
125+
gr.Textbox.update("")
126+
]

iz_helpers/prompt_util.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import json
2+
from jsonschema import validate
3+
4+
from .static_variables import (
5+
empty_prompt,
6+
invalid_prompt,
7+
jsonprompt_schemafile,
8+
promptTableHeaders
9+
)
10+
11+
def completeOptionals(j):
12+
if isinstance(j, dict):
13+
# Remove header information, user dont pimp our ui
14+
if "prompts" in j:
15+
if "headers" in j["prompts"]:
16+
del j["prompts"]["headers"]
17+
j["prompts"]["headers"]=promptTableHeaders
18+
19+
if "negPrompt" not in j:
20+
j["negPrompt"]=""
21+
22+
if "prePrompt" not in j:
23+
if "commonPromptPrefix" in j:
24+
j["prePrompt"]=j["commonPromptPrefix"]
25+
else:
26+
j["prePrompt"]=""
27+
28+
if "postPrompt" not in j:
29+
if "commonPromptSuffix" in j:
30+
j["postPrompt"]=j["commonPromptSuffix"]
31+
else:
32+
j["postPrompt"]=""
33+
34+
return j
35+
36+
37+
def validatePromptJson_throws(data):
38+
with open(jsonprompt_schemafile, "r") as s:
39+
schema = json.load(s)
40+
try:
41+
validate(instance=data, schema=schema)
42+
43+
except Exception:
44+
raise Exception("Your prompts are not schema valid.")
45+
46+
return completeOptionals(data)
47+
48+
49+
def readJsonPrompt(txt, returnFailPrompt=False):
50+
if not txt:
51+
return empty_prompt
52+
53+
try:
54+
jpr = json.loads(txt)
55+
except Exception:
56+
if returnFailPrompt:
57+
print (f"Infinite Zoom: Corrupted Json structure: {txt[:24]} ...")
58+
return invalid_prompt
59+
raise (f"Infinite Zoom: Corrupted Json structure: {txt[:24]} ...")
60+
61+
try:
62+
return validatePromptJson_throws(jpr)
63+
except Exception:
64+
if returnFailPrompt:
65+
return invalid_prompt
66+
pass
67+

iz_helpers/promptschema.json

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "1.1",
4+
"type": "object",
5+
"properties": {
6+
"prompts": {
7+
"type": "object",
8+
"properties": {
9+
"data": {
10+
"type": "array",
11+
"items": {
12+
"type": "array",
13+
"items": [
14+
{
15+
"oneOf": [
16+
{
17+
"type": "integer",
18+
"minimum": 0
19+
},
20+
{
21+
"type": "string"
22+
}
23+
]
24+
},
25+
{
26+
"type": "string"
27+
}
28+
],
29+
"minItems": 0,
30+
"maxItems": 999,
31+
"uniqueItems": false
32+
},
33+
"minItems": 0
34+
},
35+
"headers": {
36+
"type": "array",
37+
"items": {
38+
"type": "string"
39+
},
40+
"minItems": 2
41+
}
42+
},
43+
"required": [
44+
"data"
45+
]
46+
},
47+
"negPrompt": {
48+
"type": "string"
49+
},
50+
"prePrompt": {
51+
"type": "string"
52+
},
53+
"postPrompt": {
54+
"type": "string"
55+
}
56+
},
57+
"required": [
58+
"prompts"
59+
]
60+
}

0 commit comments

Comments
 (0)