Skip to content

Commit c09d7e0

Browse files
Hires Addition
Updated ImageMetaDataViewer with correct values Updated tooltip text Add arguments for Hires & Seamless Metadata
1 parent 101cac6 commit c09d7e0

19 files changed

+595
-513
lines changed

backend/invoke_ai_web_server.py

+1
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ def parameters_to_generated_image_metadata(self, parameters):
723723
'height',
724724
'extra',
725725
'seamless',
726+
'hires_fix',
726727
]
727728

728729
rfc_dict = {}

backend/modules/parameters.py

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ def parameters_to_command(params):
3636
switches.append(f'-A {params["sampler_name"]}')
3737
if "seamless" in params and params["seamless"] == True:
3838
switches.append(f"--seamless")
39+
if "hires_fix" in params and params["hires_fix"] == True:
40+
switches.append(f"--hires")
3941
if "init_img" in params and len(params["init_img"]) > 0:
4042
switches.append(f'-I {params["init_img"]}')
4143
if "init_mask" in params and len(params["init_mask"]) > 0:

backend/server.py

+1
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ def parameters_to_generated_image_metadata(parameters):
493493
"height",
494494
"extra",
495495
"seamless",
496+
"hires_fix",
496497
]
497498

498499
rfc_dict = {}

frontend/dist/assets/index.560edd47.js

+483
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/dist/assets/index.989a0ca2.js

-483
This file was deleted.

frontend/dist/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>InvokeAI - A Stable Diffusion Toolkit</title>
88
<link rel="shortcut icon" type="icon" href="/assets/favicon.0d253ced.ico" />
9-
<script type="module" crossorigin src="/assets/index.989a0ca2.js"></script>
9+
<script type="module" crossorigin src="/assets/index.560edd47.js"></script>
1010
<link rel="stylesheet" href="/assets/index.58175ea1.css">
1111
</head>
1212

frontend/src/app/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const PARAMETERS: { [key: string]: string } = {
5050
maskPath: 'Initial Image Mask',
5151
shouldFitToWidthHeight: 'Fit Initial Image',
5252
seamless: 'Seamless Tiling',
53+
hiresFix: 'High Resolution Optimizations',
5354
};
5455

5556
export const NUMPY_RAND_MIN = 0;

frontend/src/app/features.ts

+10-8
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ export enum Feature {
1414
FACE_CORRECTION,
1515
IMAGE_TO_IMAGE,
1616
}
17-
17+
/** For each tooltip in the UI, the below feature definitions & props will pull relevant information into the tooltip.
18+
*
19+
* To-do: href & GuideImages are placeholders, and are not currently utilized, but will be updated (along with the tooltip UI) as feature and UI development and we get a better idea on where things "forever homes" will be .
20+
*/
1821
export const FEATURES: Record<Feature, FeatureHelpInfo> = {
1922
[Feature.PROMPT]: {
20-
text: 'This field will take all prompt text, including both content and stylistic terms. CLI Commands will not work in the prompt.',
23+
text: 'This field will take all prompt text, including both content and stylistic terms. While weights can be included in the prompt, standard CLI Commands/parameters will not work.',
2124
href: 'link/to/docs/feature3.html',
2225
guideImage: 'asset/path.gif',
2326
},
@@ -27,17 +30,16 @@ export const FEATURES: Record<Feature, FeatureHelpInfo> = {
2730
guideImage: 'asset/path.gif',
2831
},
2932
[Feature.OTHER]: {
30-
text: 'Additional Options',
31-
href: 'link/to/docs/feature3.html',
33+
text: 'These options will enable alternative processing modes for Invoke. Seamless tiling will work to generate repeating patterns in the output. High Resolution Optimization performs a two-step generation cycle, and should be used at higher resolutions when you desire a more coherent image/composition. ', href: 'link/to/docs/feature3.html',
3234
guideImage: 'asset/path.gif',
3335
},
3436
[Feature.SEED]: {
35-
text: 'Seed values provide an initial set of noise which guide the denoising process.',
37+
text: 'Seed values provide an initial set of noise which guide the denoising process, and can be randomized or populated with a seed from a previous invocation. The Threshold feature can be used to mitigate undesirable outcomes at higher CFG values (try between 0-10), and Perlin can be used to add Perlin noise into the denoising process - Both serve to add variation to your outputs. ',
3638
href: 'link/to/docs/feature3.html',
3739
guideImage: 'asset/path.gif',
3840
},
3941
[Feature.VARIATIONS]: {
40-
text: 'Try a variation with an amount of between 0 and 1 to change the output image for the set seed.',
42+
text: 'Try a variation with an amount of between 0 and 1 to change the output image for the set seed - Interesting variations on the seed are found between 0.1 and 0.3.',
4143
href: 'link/to/docs/feature3.html',
4244
guideImage: 'asset/path.gif',
4345
},
@@ -47,8 +49,8 @@ export const FEATURES: Record<Feature, FeatureHelpInfo> = {
4749
guideImage: 'asset/path.gif',
4850
},
4951
[Feature.FACE_CORRECTION]: {
50-
text: 'Using GFPGAN or CodeFormer, Face Correction will attempt to identify faces in outputs, and correct any defects/abnormalities. Higher values will apply a stronger corrective pressure on outputs.',
51-
href: 'link/to/docs/feature2.html',
52+
text: 'Using GFPGAN, Face Correction will attempt to identify faces in outputs, and correct any defects/abnormalities. Higher values will apply a stronger corrective pressure on outputs, resulting in more appealing faces (with less respect for accuracy of the original subject).',
53+
href: 'link/to/docs/feature3.html',
5254
guideImage: 'asset/path.gif',
5355
},
5456
[Feature.IMAGE_TO_IMAGE]: {

frontend/src/app/invokeai.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export declare type CommonGeneratedImageMetadata = {
5555
width: number;
5656
height: number;
5757
seamless: boolean;
58+
hires_fix: boolean;
5859
extra: null | Record<string, never>; // Pending development of RFC #266
5960
};
6061

frontend/src/common/util/parameterTranslation.ts

+4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export const frontendToBackendParameters = (
2929
sampler,
3030
seed,
3131
seamless,
32+
hiresFix,
3233
shouldUseInitImage,
3334
img2imgStrength,
3435
initialImagePath,
@@ -59,6 +60,7 @@ export const frontendToBackendParameters = (
5960
sampler_name: sampler,
6061
seed,
6162
seamless,
63+
hires_fix: hiresFix,
6264
progress_images: shouldDisplayInProgress,
6365
};
6466

@@ -123,6 +125,7 @@ export const backendToFrontendParameters = (parameters: {
123125
sampler_name,
124126
seed,
125127
seamless,
128+
hires_fix,
126129
progress_images,
127130
variation_amount,
128131
with_variations,
@@ -185,6 +188,7 @@ export const backendToFrontendParameters = (parameters: {
185188
options.sampler = sampler_name;
186189
options.seed = seed;
187190
options.seamless = seamless;
191+
options.hiresFix = hires_fix;
188192
}
189193

190194
return options;

frontend/src/features/gallery/ImageMetaDataViewer/ImageMetadataViewer.tsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ import {
1616
setCfgScale,
1717
setGfpganStrength,
1818
setHeight,
19+
setHiresFix,
1920
setImg2imgStrength,
2021
setInitialImagePath,
2122
setMaskPath,
2223
setPrompt,
2324
setSampler,
25+
setSeamless,
2426
setSeed,
2527
setSeedWeights,
2628
setShouldFitToWidthHeight,
@@ -116,6 +118,7 @@ const ImageMetadataViewer = memo(
116118
steps,
117119
cfg_scale,
118120
seamless,
121+
hires_fix,
119122
width,
120123
height,
121124
strength,
@@ -214,7 +217,14 @@ const ImageMetadataViewer = memo(
214217
<MetadataItem
215218
label="Seamless"
216219
value={seamless}
217-
onClick={() => dispatch(setWidth(seamless))}
220+
onClick={() => dispatch(setSeamless(seamless))}
221+
/>
222+
)}
223+
{hires_fix && (
224+
<MetadataItem
225+
label="High Resolution Optimization"
226+
value={hires_fix}
227+
onClick={() => dispatch(setHiresFix(hires_fix))}
218228
/>
219229
)}
220230
{width && (
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Flex } from '@chakra-ui/react';
2+
import { RootState } from '../../app/store';
3+
import { useAppDispatch, useAppSelector } from '../../app/store';
4+
import { setHiresFix } from './optionsSlice';
5+
import { ChangeEvent } from 'react';
6+
import IAISwitch from '../../common/components/IAISwitch';
7+
8+
/**
9+
* Image output options. Includes width, height, seamless tiling.
10+
*/
11+
const HiresOptions = () => {
12+
const dispatch = useAppDispatch();
13+
14+
const hiresFix = useAppSelector((state: RootState) => state.options.hiresFix);
15+
16+
const handleChangeHiresFix = (e: ChangeEvent<HTMLInputElement>) =>
17+
dispatch(setHiresFix(e.target.checked));
18+
19+
20+
return (
21+
<Flex gap={2} direction={'column'}>
22+
<IAISwitch
23+
label="High Res Optimization"
24+
fontSize={'md'}
25+
isChecked={hiresFix}
26+
onChange={handleChangeHiresFix}
27+
/>
28+
</Flex>
29+
);
30+
};
31+
32+
export default HiresOptions;

frontend/src/features/options/OutputOptions.tsx

+5-20
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,14 @@
11
import { Flex } from '@chakra-ui/react';
2-
import { RootState } from '../../app/store';
3-
import { useAppDispatch, useAppSelector } from '../../app/store';
4-
import { setSeamless } from './optionsSlice';
5-
import { ChangeEvent } from 'react';
6-
import IAISwitch from '../../common/components/IAISwitch';
72

8-
/**
9-
* Image output options. Includes width, height, seamless tiling.
10-
*/
11-
const OutputOptions = () => {
12-
const dispatch = useAppDispatch();
13-
14-
const seamless = useAppSelector((state: RootState) => state.options.seamless);
3+
import HiresOptions from './HiresOptions';
4+
import SeamlessOptions from './SeamlessOptions';
155

16-
const handleChangeSeamless = (e: ChangeEvent<HTMLInputElement>) =>
17-
dispatch(setSeamless(e.target.checked));
6+
const OutputOptions = () => {
187

198
return (
209
<Flex gap={2} direction={'column'}>
21-
<IAISwitch
22-
label="Seamless tiling"
23-
fontSize={'md'}
24-
isChecked={seamless}
25-
onChange={handleChangeSeamless}
26-
/>
10+
<SeamlessOptions />
11+
<HiresOptions />
2712
</Flex>
2813
);
2914
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Flex } from '@chakra-ui/react';
2+
import { RootState } from '../../app/store';
3+
import { useAppDispatch, useAppSelector } from '../../app/store';
4+
import { setSeamless } from './optionsSlice';
5+
import { ChangeEvent } from 'react';
6+
import IAISwitch from '../../common/components/IAISwitch';
7+
8+
const SeamlessOptions = () => {
9+
const dispatch = useAppDispatch();
10+
11+
const seamless = useAppSelector((state: RootState) => state.options.seamless);
12+
13+
const handleChangeSeamless = (e: ChangeEvent<HTMLInputElement>) =>
14+
dispatch(setSeamless(e.target.checked));
15+
16+
return (
17+
<Flex gap={2} direction={'column'}>
18+
<IAISwitch
19+
label="Seamless tiling"
20+
fontSize={'md'}
21+
isChecked={seamless}
22+
onChange={handleChangeSeamless}
23+
/>
24+
</Flex>
25+
);
26+
};
27+
28+
export default SeamlessOptions;

frontend/src/features/options/optionsSlice.ts

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface OptionsState {
2525
initialImagePath: string | null;
2626
maskPath: string;
2727
seamless: boolean;
28+
hiresFix: boolean;
2829
shouldFitToWidthHeight: boolean;
2930
shouldGenerateVariations: boolean;
3031
variationAmount: number;
@@ -50,6 +51,7 @@ const initialOptionsState: OptionsState = {
5051
perlin: 0,
5152
seed: 0,
5253
seamless: false,
54+
hiresFix: false,
5355
shouldUseInitImage: false,
5456
img2imgStrength: 0.75,
5557
initialImagePath: null,
@@ -138,6 +140,9 @@ export const optionsSlice = createSlice({
138140
setSeamless: (state, action: PayloadAction<boolean>) => {
139141
state.seamless = action.payload;
140142
},
143+
setHiresFix: (state, action: PayloadAction<boolean>) => {
144+
state.hiresFix = action.payload;
145+
},
141146
setShouldFitToWidthHeight: (state, action: PayloadAction<boolean>) => {
142147
state.shouldFitToWidthHeight = action.payload;
143148
},
@@ -180,6 +185,7 @@ export const optionsSlice = createSlice({
180185
threshold,
181186
perlin,
182187
seamless,
188+
hires_fix,
183189
width,
184190
height,
185191
strength,
@@ -256,6 +262,7 @@ export const optionsSlice = createSlice({
256262
if (perlin) state.perlin = perlin;
257263
if (typeof perlin === 'undefined') state.perlin = 0;
258264
if (typeof seamless === 'boolean') state.seamless = seamless;
265+
if (typeof hires_fix === 'boolean') state.hiresFix = hires_fix;
259266
if (width) state.width = width;
260267
if (height) state.height = height;
261268
},
@@ -301,6 +308,7 @@ export const {
301308
setSampler,
302309
setSeed,
303310
setSeamless,
311+
setHiresFix,
304312
setImg2imgStrength,
305313
setGfpganStrength,
306314
setUpscalingLevel,

ldm/generate.py

+3
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ def __init__(
155155
self.precision = precision
156156
self.strength = 0.75
157157
self.seamless = False
158+
self.hires_fix = False
158159
self.embedding_path = embedding_path
159160
self.model = None # empty for now
160161
self.sampler = None
@@ -269,6 +270,7 @@ def prompt2image(
269270
height // height of image, in multiples of 64 (512)
270271
cfg_scale // how strongly the prompt influences the image (7.5) (must be >1)
271272
seamless // whether the generated image should tile
273+
hires_fix // whether the Hires Fix should be applied during generation
272274
init_img // path to an initial image
273275
strength // strength for noising/unnoising init_img. 0.0 preserves image exactly, 1.0 replaces it completely
274276
gfpgan_strength // strength for GFPGAN. 0.0 preserves image exactly, 1.0 replaces it completely
@@ -302,6 +304,7 @@ def process_image(image,seed):
302304
width = width or self.width
303305
height = height or self.height
304306
seamless = seamless or self.seamless
307+
hires_fix = hires_fix or self.hires_fix
305308
cfg_scale = cfg_scale or self.cfg_scale
306309
ddim_eta = ddim_eta or self.ddim_eta
307310
iterations = iterations or self.iterations

ldm/invoke/server.py

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def build_opt(post_data, seed, gfpgan_model_exists):
3737
setattr(opt, 'seed', None if int(post_data['seed']) == -1 else int(post_data['seed']))
3838
setattr(opt, 'threshold', float(post_data['threshold']))
3939
setattr(opt, 'perlin', float(post_data['perlin']))
40+
setattr(opt, 'hires_fix', 'hires_fix' in post_data)
4041
setattr(opt, 'variation_amount', float(post_data['variation_amount']) if int(post_data['seed']) != -1 else 0)
4142
setattr(opt, 'with_variations', [])
4243
setattr(opt, 'embiggen', None)

server/models.py

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class DreamBase():
3535
perlin: float = 0.0
3636
sampler_name: string = 'klms'
3737
seamless: bool = False
38+
hires_fix: bool = False
3839
model: str = None # The model to use (currently unused)
3940
embeddings = None # The embeddings to use (currently unused)
4041
progress_images: bool = False
@@ -91,6 +92,7 @@ def parse_json(self, j, new_instance=False):
9192
# model: str = None # The model to use (currently unused)
9293
# embeddings = None # The embeddings to use (currently unused)
9394
self.seamless = 'seamless' in j
95+
self.hires_fix = 'hires_fix' in j
9496
self.progress_images = 'progress_images' in j
9597

9698
# GFPGAN

server/services.py

+1
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ def __generate(self, jobRequest: JobRequest):
375375
upscale = upscale,
376376
sampler_name = jobRequest.sampler_name,
377377
seamless = jobRequest.seamless,
378+
hires_fix = jobRequest.hires_fix,
378379
embiggen = jobRequest.embiggen,
379380
embiggen_tiles = jobRequest.embiggen_tiles,
380381
step_callback = lambda sample, step: self.__on_progress(jobRequest, sample, step),

0 commit comments

Comments
 (0)