[WebUI] Fix 'Use All' Params not Respecting Hi-Res Fix (#2840)

This is a different source/base branch from
https://github.com/invoke-ai/InvokeAI/pull/2823 but is otherwise the
same content. `yarn build` was ran on this clean branch.

## What was the problem/requirement? (What/Why)
As part of a [change in
2.3.0](d74c4009cb),
the high resolution fix was no longer being applied when 'Use all' was
selected. This effectively meant that users had to manually analyze
images to ensure that the parameters were set to match.
~~Additionally, and never actually working, Upscaling and Face
Restoration parameters were also not pulling through with the action,
causing a similar usability issue.~~ See:
https://github.com/invoke-ai/InvokeAI/pull/2823#issuecomment-1445530362

## What was the solution? (How)
This change adds a new reducer to the `postprocessingSlice` file,
mimicking the `generationSlice` reducer to assign all parameters
appropriate for the post processing options. This reducer assigns:
* Hi-res's toggle button only if the type is `txt2img`, since `img2img`
hi-res was removed previously
* ~~Upscaling's toggle button, scale, denoising strength, and upscale
strength~~
* ~~Face Restoration's toggle button, type, strength, and fidelity (if
present/applicable)~~

### Minor
* Added `endOfLine: 'crlf'` to prettier's config to prevent all files
from being checked out on Windows due to difference of line endings (and
git not picking up those changes as modifications, causing ghost
modified files from Git)

### Revision 2:
* Removed out upscaling and face restoration pulling of parameters
### Revision 3:
* More defensive coding for the `hires_fix` not present (assume false)

### Out of Scope
* Hi-res strength (applied as img2img strength in the initial image that
is generated) is not in the metadata of the final image and can't be
reconstructed easily
* Upscaling and face restoration have some peculiarities for multi-post
processing outside of the UI, which complicates it enough to scope out
of this PR.

## How were these changes tested?
* `yarn dev` => Server started successfully
* Manual testing on the development server to ensure parameters pulled
correctly
* `yarn build` => Success

## Notes
As with `generationSlice`, this code assumes `action.payload.image` is
valid and doesn't do a formal check on it to ensure it is valid.
This commit is contained in:
blessedcoolant 2023-03-08 22:38:41 +13:00 committed by GitHub
commit 5a633ba811
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 67 additions and 48 deletions

View File

@ -1,6 +1,7 @@
module.exports = {
trailingComma: 'es5',
tabWidth: 2,
endOfLine: 'auto',
semi: true,
singleQuote: true,
overrides: [

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>InvokeAI - A Stable Diffusion Toolkit</title>
<link rel="shortcut icon" type="icon" href="./assets/favicon-0d253ced.ico" />
<script type="module" crossorigin src="./assets/index-c33fa9da.js"></script>
<script type="module" crossorigin src="./assets/index-720872d1.js"></script>
<link rel="stylesheet" href="./assets/index-14cb2922.css">
</head>

View File

@ -21,6 +21,7 @@ import {
setInitialImage,
setSeed,
} from 'features/parameters/store/generationSlice';
import { setAllPostProcessingParameters } from 'features/parameters/store/postprocessingSlice';
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
import { systemSelector } from 'features/system/store/systemSelectors';
import { SystemState } from 'features/system/store/systemSlice';
@ -189,11 +190,12 @@ const CurrentImageButtons = () => {
);
const handleClickUseAllParameters = () => {
if (!currentImage) return;
currentImage.metadata && dispatch(setAllParameters(currentImage.metadata));
if (currentImage.metadata?.image.type === 'img2img') {
if (!currentImage?.metadata) return;
dispatch(setAllParameters(currentImage.metadata));
dispatch(setAllPostProcessingParameters(currentImage.metadata));
if (currentImage.metadata.image.type === 'img2img') {
dispatch(setActiveTab('img2img'));
} else if (currentImage.metadata?.image.type === 'txt2img') {
} else if (currentImage.metadata.image.type === 'txt2img') {
dispatch(setActiveTab('txt2img'));
}
};

View File

@ -10,6 +10,7 @@ import {
setInitialImage,
setSeed,
} from 'features/parameters/store/generationSlice';
import { setAllPostProcessingParameters } from 'features/parameters/store/postprocessingSlice';
import { DragEvent, memo, useState } from 'react';
import { FaCheck, FaTrashAlt } from 'react-icons/fa';
import DeleteImageModal from './DeleteImageModal';
@ -114,7 +115,10 @@ const HoverableImage = memo((props: HoverableImageProps) => {
};
const handleUseAllParameters = () => {
metadata && dispatch(setAllParameters(metadata));
if (metadata) {
dispatch(setAllParameters(metadata));
dispatch(setAllPostProcessingParameters(metadata));
}
toast({
title: t('toast.parametersSet'),
status: 'success',

View File

@ -301,7 +301,6 @@ export const generationSlice = createSlice({
state.perlin = perlin;
}
if (typeof seamless === 'boolean') state.seamless = seamless;
// if (typeof hires_fix === 'boolean') state.hiresFix = hires_fix; // TODO: Needs to be fixed after reorg
if (width) state.width = width;
if (height) state.height = height;

View File

@ -1,5 +1,6 @@
import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
import * as InvokeAI from 'app/invokeai';
import { FACETOOL_TYPES } from 'app/constants';
export type UpscalingLevel = 2 | 4;
@ -40,6 +41,17 @@ export const postprocessingSlice = createSlice({
name: 'postprocessing',
initialState,
reducers: {
setAllPostProcessingParameters: (
state,
action: PayloadAction<InvokeAI.Metadata>
) => {
const { type, hires_fix } = action.payload.image;
if (type === 'txt2img') {
state.hiresFix = Boolean(hires_fix);
// Strength of img2img used in hires_fix is not currently exposed in the Metadata for the final image.
}
},
setFacetoolStrength: (state, action: PayloadAction<number>) => {
state.facetoolStrength = action.payload;
},
@ -83,6 +95,7 @@ export const postprocessingSlice = createSlice({
});
export const {
setAllPostProcessingParameters,
resetPostprocessingState,
setCodeformerFidelity,
setFacetoolStrength,

View File

@ -1180,7 +1180,7 @@ def metadata_dumps(opt,
)
# remove any image keys not mentioned in RFC #266
rfc266_img_fields = ['type','postprocessing','sampler','prompt','seed','variations','steps',
rfc266_img_fields = ['type','postprocessing','sampler','prompt','seed','variations','steps','hires_fix',
'cfg_scale','threshold','perlin','step_number','width','height','extra','strength','seamless'
'init_img','init_mask','facetool','facetool_strength','upscale','h_symmetry_time_pct',
'v_symmetry_time_pct']