mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Adds Codeformer support
This commit is contained in:
parent
62dd3b7d7d
commit
32a5ffe436
@ -257,14 +257,14 @@ class InvokeAIWebServer:
|
||||
|
||||
@socketio.on('generateImage')
|
||||
def handle_generate_image_event(
|
||||
generation_parameters, esrgan_parameters, gfpgan_parameters
|
||||
generation_parameters, esrgan_parameters, facetool_parameters
|
||||
):
|
||||
try:
|
||||
print(
|
||||
f'>> Image generation requested: {generation_parameters}\nESRGAN parameters: {esrgan_parameters}\nGFPGAN parameters: {gfpgan_parameters}'
|
||||
f'>> Image generation requested: {generation_parameters}\nESRGAN parameters: {esrgan_parameters}\nFacetool parameters: {facetool_parameters}'
|
||||
)
|
||||
self.generate_images(
|
||||
generation_parameters, esrgan_parameters, gfpgan_parameters
|
||||
generation_parameters, esrgan_parameters, facetool_parameters
|
||||
)
|
||||
except Exception as e:
|
||||
self.socketio.emit('error', {'message': (str(e))})
|
||||
@ -300,9 +300,11 @@ class InvokeAIWebServer:
|
||||
)
|
||||
|
||||
if postprocessing_parameters['type'] == 'esrgan':
|
||||
progress.set_current_status('Upscaling')
|
||||
progress.set_current_status('Upscaling (ESRGAN)')
|
||||
elif postprocessing_parameters['type'] == 'gfpgan':
|
||||
progress.set_current_status('Restoring Faces')
|
||||
progress.set_current_status('Restoring Faces (GFPGAN)')
|
||||
elif postprocessing_parameters['type'] == 'codeformer':
|
||||
progress.set_current_status('Restoring Faces (Codeformer)')
|
||||
|
||||
socketio.emit('progressUpdate', progress.to_formatted_dict())
|
||||
eventlet.sleep(0)
|
||||
@ -322,6 +324,14 @@ class InvokeAIWebServer:
|
||||
strength=postprocessing_parameters['facetool_strength'],
|
||||
seed=seed,
|
||||
)
|
||||
elif postprocessing_parameters['type'] == 'codeformer':
|
||||
image = self.codeformer.process(
|
||||
image=image,
|
||||
strength=postprocessing_parameters['facetool_strength'],
|
||||
fidelity=postprocessing_parameters['codeformer_fidelity'],
|
||||
seed=seed,
|
||||
device='cpu' if str(self.generate.device) == 'mps' else self.generate.device
|
||||
)
|
||||
else:
|
||||
raise TypeError(
|
||||
f'{postprocessing_parameters["type"]} is not a valid postprocessing type'
|
||||
@ -448,7 +458,7 @@ class InvokeAIWebServer:
|
||||
}
|
||||
|
||||
def generate_images(
|
||||
self, generation_parameters, esrgan_parameters, gfpgan_parameters
|
||||
self, generation_parameters, esrgan_parameters, facetool_parameters
|
||||
):
|
||||
try:
|
||||
self.canceled.clear()
|
||||
@ -551,7 +561,7 @@ class InvokeAIWebServer:
|
||||
|
||||
nonlocal generation_parameters
|
||||
nonlocal esrgan_parameters
|
||||
nonlocal gfpgan_parameters
|
||||
nonlocal facetool_parameters
|
||||
nonlocal progress
|
||||
|
||||
step_index = 1
|
||||
@ -611,23 +621,41 @@ class InvokeAIWebServer:
|
||||
if self.canceled.is_set():
|
||||
raise CanceledException
|
||||
|
||||
if gfpgan_parameters:
|
||||
progress.set_current_status('Restoring Faces')
|
||||
if facetool_parameters:
|
||||
if facetool_parameters['type'] == 'gfpgan':
|
||||
progress.set_current_status('Restoring Faces (GFPGAN)')
|
||||
elif facetool_parameters['type'] == 'codeformer':
|
||||
progress.set_current_status('Restoring Faces (Codeformer)')
|
||||
|
||||
progress.set_current_status_has_steps(False)
|
||||
self.socketio.emit(
|
||||
'progressUpdate', progress.to_formatted_dict()
|
||||
)
|
||||
eventlet.sleep(0)
|
||||
|
||||
image = self.gfpgan.process(
|
||||
image=image,
|
||||
strength=gfpgan_parameters['strength'],
|
||||
seed=seed,
|
||||
)
|
||||
if facetool_parameters['type'] == 'gfpgan':
|
||||
image = self.gfpgan.process(
|
||||
image=image,
|
||||
strength=facetool_parameters['strength'],
|
||||
seed=seed,
|
||||
)
|
||||
elif facetool_parameters['type'] == 'codeformer':
|
||||
image = self.codeformer.process(
|
||||
image=image,
|
||||
strength=facetool_parameters['strength'],
|
||||
fidelity=facetool_parameters['codeformer_fidelity'],
|
||||
seed=seed,
|
||||
device='cpu' if str(self.generate.device) == 'mps' else self.generate.device,
|
||||
)
|
||||
all_parameters['codeformer_fidelity'] = facetool_parameters['codeformer_fidelity']
|
||||
|
||||
postprocessing = True
|
||||
all_parameters['facetool_strength'] = gfpgan_parameters[
|
||||
all_parameters['facetool_strength'] = facetool_parameters[
|
||||
'strength'
|
||||
]
|
||||
all_parameters['facetool_type'] = facetool_parameters[
|
||||
'type'
|
||||
]
|
||||
|
||||
progress.set_current_status('Saving Image')
|
||||
self.socketio.emit(
|
||||
@ -737,13 +765,15 @@ class InvokeAIWebServer:
|
||||
|
||||
# 'postprocessing' is either null or an
|
||||
if 'facetool_strength' in parameters:
|
||||
|
||||
postprocessing.append(
|
||||
{
|
||||
'type': 'gfpgan',
|
||||
facetool_parameters = {
|
||||
'type': str(parameters['facetool_type']),
|
||||
'strength': float(parameters['facetool_strength']),
|
||||
}
|
||||
)
|
||||
|
||||
if parameters['facetool_type'] == 'codeformer':
|
||||
facetool_parameters['fidelity'] = float(parameters['codeformer_fidelity'])
|
||||
|
||||
postprocessing.append(facetool_parameters)
|
||||
|
||||
if 'upscale' in parameters:
|
||||
postprocessing.append(
|
||||
@ -840,6 +870,13 @@ class InvokeAIWebServer:
|
||||
postprocessing_metadata['strength'] = parameters[
|
||||
'facetool_strength'
|
||||
]
|
||||
elif parameters['type'] == 'codeformer':
|
||||
postprocessing_metadata['type'] = 'codeformer'
|
||||
postprocessing_metadata['strength'] = parameters[
|
||||
'facetool_strength'
|
||||
]
|
||||
postprocessing_metadata['fidelity'] = parameters['codeformer_fidelity']
|
||||
|
||||
else:
|
||||
raise TypeError(f"Invalid type: {parameters['type']}")
|
||||
|
||||
|
482
frontend/dist/assets/index.89883620.js
vendored
482
frontend/dist/assets/index.89883620.js
vendored
File diff suppressed because one or more lines are too long
690
frontend/dist/assets/index.ef6347d3.js
vendored
Normal file
690
frontend/dist/assets/index.ef6347d3.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
frontend/dist/index.html
vendored
4
frontend/dist/index.html
vendored
@ -6,7 +6,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.89883620.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index.ef6347d3.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index.58175ea1.css">
|
||||
</head>
|
||||
|
||||
@ -15,4 +15,4 @@
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
@ -43,7 +43,7 @@ export const PARAMETERS: { [key: string]: string } = {
|
||||
sampler: 'Sampler',
|
||||
seed: 'Seed',
|
||||
img2imgStrength: 'img2img Strength',
|
||||
gfpganStrength: 'GFPGAN Strength',
|
||||
facetoolStrength: 'GFPGAN Strength',
|
||||
upscalingLevel: 'Upscaling Level',
|
||||
upscalingStrength: 'Upscaling Strength',
|
||||
initialImagePath: 'Initial Image',
|
||||
@ -56,3 +56,5 @@ export const PARAMETERS: { [key: string]: string } = {
|
||||
export const NUMPY_RAND_MIN = 0;
|
||||
|
||||
export const NUMPY_RAND_MAX = 4294967295;
|
||||
|
||||
export const FACETOOL_TYPES = ['gfpgan', 'codeformer'] as const;
|
||||
|
7
frontend/src/app/invokeai.d.ts
vendored
7
frontend/src/app/invokeai.d.ts
vendored
@ -89,15 +89,16 @@ export declare type ESRGANMetadata = CommonPostProcessedImageMetadata & {
|
||||
strength: number;
|
||||
};
|
||||
|
||||
export declare type GFPGANMetadata = CommonPostProcessedImageMetadata & {
|
||||
type: 'gfpgan';
|
||||
export declare type FacetoolMetadata = CommonPostProcessedImageMetadata & {
|
||||
type: 'gfpgan' | 'codeformer';
|
||||
strength: number;
|
||||
fidelity?: number;
|
||||
};
|
||||
|
||||
// Superset of all postprocessed image metadata types..
|
||||
export declare type PostProcessedImageMetadata =
|
||||
| ESRGANMetadata
|
||||
| GFPGANMetadata;
|
||||
| FacetoolMetadata;
|
||||
|
||||
// Metadata includes the system config and image metadata.
|
||||
export declare type Metadata = SystemConfig & {
|
||||
|
@ -30,14 +30,14 @@ const makeSocketIOEmitters = (
|
||||
options.shouldUseInitImage = false;
|
||||
}
|
||||
|
||||
const { generationParameters, esrganParameters, gfpganParameters } =
|
||||
const { generationParameters, esrganParameters, facetoolParameters } =
|
||||
frontendToBackendParameters(options, getState().system);
|
||||
|
||||
socketio.emit(
|
||||
'generateImage',
|
||||
generationParameters,
|
||||
esrganParameters,
|
||||
gfpganParameters
|
||||
facetoolParameters
|
||||
);
|
||||
|
||||
dispatch(
|
||||
@ -46,7 +46,7 @@ const makeSocketIOEmitters = (
|
||||
message: `Image generation requested: ${JSON.stringify({
|
||||
...generationParameters,
|
||||
...esrganParameters,
|
||||
...gfpganParameters,
|
||||
...facetoolParameters,
|
||||
})}`,
|
||||
})
|
||||
);
|
||||
@ -71,24 +71,32 @@ const makeSocketIOEmitters = (
|
||||
})
|
||||
);
|
||||
},
|
||||
emitRunGFPGAN: (imageToProcess: InvokeAI.Image) => {
|
||||
emitRunFacetool: (imageToProcess: InvokeAI.Image) => {
|
||||
dispatch(setIsProcessing(true));
|
||||
const { gfpganStrength } = getState().options;
|
||||
const { facetoolType, facetoolStrength, codeformerFidelity } =
|
||||
getState().options;
|
||||
|
||||
const gfpganParameters = {
|
||||
facetool_strength: gfpganStrength,
|
||||
const facetoolParameters: Record<string, any> = {
|
||||
facetool_strength: facetoolStrength,
|
||||
};
|
||||
|
||||
if (facetoolType === 'codeformer') {
|
||||
facetoolParameters.codeformer_fidelity = codeformerFidelity;
|
||||
}
|
||||
|
||||
socketio.emit('runPostprocessing', imageToProcess, {
|
||||
type: 'gfpgan',
|
||||
...gfpganParameters,
|
||||
type: facetoolType,
|
||||
...facetoolParameters,
|
||||
});
|
||||
dispatch(
|
||||
addLogEntry({
|
||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||
message: `GFPGAN fix faces requested: ${JSON.stringify({
|
||||
file: imageToProcess.url,
|
||||
...gfpganParameters,
|
||||
})}`,
|
||||
message: `Face restoration (${facetoolType}) requested: ${JSON.stringify(
|
||||
{
|
||||
file: imageToProcess.url,
|
||||
...facetoolParameters,
|
||||
}
|
||||
)}`,
|
||||
})
|
||||
);
|
||||
},
|
||||
|
@ -151,32 +151,6 @@ const makeSocketIOListeners = (
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Callback to run when we receive a 'gfpganResult' event.
|
||||
*/
|
||||
onGFPGANResult: (data: InvokeAI.ImageResultResponse) => {
|
||||
try {
|
||||
const { url, metadata, mtime } = data;
|
||||
|
||||
dispatch(
|
||||
addImage({
|
||||
uuid: uuidv4(),
|
||||
url,
|
||||
mtime,
|
||||
metadata,
|
||||
})
|
||||
);
|
||||
|
||||
dispatch(
|
||||
addLogEntry({
|
||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||
message: `Fixed faces: ${url}`,
|
||||
})
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Callback to run when we receive a 'progressUpdate' event.
|
||||
* TODO: Add additional progress phases
|
||||
|
@ -50,7 +50,7 @@ export const socketioMiddleware = () => {
|
||||
const {
|
||||
emitGenerateImage,
|
||||
emitRunESRGAN,
|
||||
emitRunGFPGAN,
|
||||
emitRunFacetool: emitRunGFPGAN,
|
||||
emitDeleteImage,
|
||||
emitRequestImages,
|
||||
emitRequestNewImages,
|
||||
|
@ -41,8 +41,10 @@ export const frontendToBackendParameters = (
|
||||
shouldRunESRGAN,
|
||||
upscalingLevel,
|
||||
upscalingStrength,
|
||||
shouldRunGFPGAN,
|
||||
gfpganStrength,
|
||||
shouldRunFacetool,
|
||||
facetoolStrength,
|
||||
codeformerFidelity,
|
||||
facetoolType,
|
||||
shouldRandomizeSeed,
|
||||
} = optionsState;
|
||||
|
||||
@ -88,7 +90,7 @@ export const frontendToBackendParameters = (
|
||||
}
|
||||
|
||||
let esrganParameters: false | { [k: string]: any } = false;
|
||||
let gfpganParameters: false | { [k: string]: any } = false;
|
||||
let facetoolParameters: false | { [k: string]: any } = false;
|
||||
|
||||
if (shouldRunESRGAN) {
|
||||
esrganParameters = {
|
||||
@ -97,99 +99,19 @@ export const frontendToBackendParameters = (
|
||||
};
|
||||
}
|
||||
|
||||
if (shouldRunGFPGAN) {
|
||||
gfpganParameters = {
|
||||
strength: gfpganStrength,
|
||||
if (shouldRunFacetool) {
|
||||
facetoolParameters = {
|
||||
type: facetoolType,
|
||||
strength: facetoolStrength,
|
||||
};
|
||||
if (facetoolType === 'codeformer') {
|
||||
facetoolParameters.codeformer_fidelity = codeformerFidelity
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
generationParameters,
|
||||
esrganParameters,
|
||||
gfpganParameters,
|
||||
facetoolParameters,
|
||||
};
|
||||
};
|
||||
|
||||
export const backendToFrontendParameters = (parameters: {
|
||||
[key: string]: any;
|
||||
}) => {
|
||||
const {
|
||||
prompt,
|
||||
iterations,
|
||||
steps,
|
||||
cfg_scale,
|
||||
threshold,
|
||||
perlin,
|
||||
height,
|
||||
width,
|
||||
sampler_name,
|
||||
seed,
|
||||
seamless,
|
||||
hires_fix,
|
||||
progress_images,
|
||||
variation_amount,
|
||||
with_variations,
|
||||
facetool_strength,
|
||||
upscale,
|
||||
init_img,
|
||||
init_mask,
|
||||
strength,
|
||||
} = parameters;
|
||||
|
||||
const options: { [key: string]: any } = {
|
||||
shouldDisplayInProgress: progress_images,
|
||||
// init
|
||||
shouldGenerateVariations: false,
|
||||
shouldRunESRGAN: false,
|
||||
shouldRunGFPGAN: false,
|
||||
initialImagePath: '',
|
||||
maskPath: '',
|
||||
};
|
||||
|
||||
if (variation_amount > 0) {
|
||||
options.shouldGenerateVariations = true;
|
||||
options.variationAmount = variation_amount;
|
||||
if (with_variations) {
|
||||
options.seedWeights = seedWeightsToString(with_variations);
|
||||
}
|
||||
}
|
||||
|
||||
if (facetool_strength > 0) {
|
||||
options.shouldRunGFPGAN = true;
|
||||
options.gfpganStrength = facetool_strength;
|
||||
}
|
||||
|
||||
if (upscale) {
|
||||
options.shouldRunESRGAN = true;
|
||||
options.upscalingLevel = upscale[0];
|
||||
options.upscalingStrength = upscale[1];
|
||||
}
|
||||
|
||||
if (init_img) {
|
||||
options.shouldUseInitImage = true;
|
||||
options.initialImagePath = init_img;
|
||||
options.strength = strength;
|
||||
if (init_mask) {
|
||||
options.maskPath = init_mask;
|
||||
}
|
||||
}
|
||||
|
||||
// if we had a prompt, add all the metadata, but if we don't have a prompt,
|
||||
// we must have only done ESRGAN or GFPGAN so do not add that metadata
|
||||
if (prompt) {
|
||||
options.prompt = prompt;
|
||||
options.iterations = iterations;
|
||||
options.steps = steps;
|
||||
options.cfgScale = cfg_scale;
|
||||
options.threshold = threshold;
|
||||
options.perlin = perlin;
|
||||
options.height = height;
|
||||
options.width = width;
|
||||
options.sampler = sampler_name;
|
||||
options.seed = seed;
|
||||
options.seamless = seamless;
|
||||
options.hiresFix = hires_fix;
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
||||
|
@ -66,8 +66,8 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
||||
(state: RootState) => state.options.upscalingLevel
|
||||
);
|
||||
|
||||
const gfpganStrength = useAppSelector(
|
||||
(state: RootState) => state.options.gfpganStrength
|
||||
const facetoolStrength = useAppSelector(
|
||||
(state: RootState) => state.options.facetoolStrength
|
||||
);
|
||||
|
||||
const { isProcessing, isConnected, isGFPGANAvailable, isESRGANAvailable } =
|
||||
@ -195,7 +195,7 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
||||
Boolean(!intermediateImage) &&
|
||||
isConnected &&
|
||||
!isProcessing &&
|
||||
gfpganStrength
|
||||
facetoolStrength
|
||||
) {
|
||||
handleClickFixFaces();
|
||||
} else {
|
||||
@ -213,7 +213,7 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
||||
intermediateImage,
|
||||
isConnected,
|
||||
isProcessing,
|
||||
gfpganStrength,
|
||||
facetoolStrength,
|
||||
]
|
||||
);
|
||||
|
||||
@ -270,7 +270,7 @@ const CurrentImageButtons = ({ image }: CurrentImageButtonsProps) => {
|
||||
!isGFPGANAvailable ||
|
||||
Boolean(intermediateImage) ||
|
||||
!(isConnected && !isProcessing) ||
|
||||
!gfpganStrength
|
||||
!facetoolStrength
|
||||
}
|
||||
onClick={handleClickFixFaces}
|
||||
/>
|
||||
|
@ -14,7 +14,9 @@ import { useAppDispatch } from '../../../app/store';
|
||||
import * as InvokeAI from '../../../app/invokeai';
|
||||
import {
|
||||
setCfgScale,
|
||||
setGfpganStrength,
|
||||
setFacetoolStrength,
|
||||
setCodeformerFidelity,
|
||||
setFacetoolType,
|
||||
setHeight,
|
||||
setHiresFix,
|
||||
setImg2imgStrength,
|
||||
@ -151,7 +153,7 @@ const ImageMetadataViewer = memo(
|
||||
<MetadataItem
|
||||
label="Fix faces strength"
|
||||
value={strength}
|
||||
onClick={() => dispatch(setGfpganStrength(strength))}
|
||||
onClick={() => dispatch(setFacetoolStrength(strength))}
|
||||
/>
|
||||
)}
|
||||
{type === 'esrgan' && scale !== undefined && (
|
||||
@ -321,12 +323,46 @@ const ImageMetadataViewer = memo(
|
||||
<MetadataItem
|
||||
label="Strength"
|
||||
value={strength}
|
||||
onClick={() =>
|
||||
dispatch(setGfpganStrength(strength))
|
||||
}
|
||||
onClick={() => {
|
||||
dispatch(setFacetoolStrength(strength));
|
||||
dispatch(setFacetoolType('gfpgan'));
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
} else if (postprocess.type === 'codeformer') {
|
||||
const { strength, fidelity } = postprocess;
|
||||
return (
|
||||
<Flex
|
||||
key={i}
|
||||
pl={'2rem'}
|
||||
gap={1}
|
||||
direction={'column'}
|
||||
>
|
||||
<Text size={'md'}>{`${
|
||||
i + 1
|
||||
}: Face restoration (Codeformer)`}</Text>
|
||||
|
||||
<MetadataItem
|
||||
label="Strength"
|
||||
value={strength}
|
||||
onClick={() => {
|
||||
dispatch(setFacetoolStrength(strength));
|
||||
dispatch(setFacetoolType('codeformer'));
|
||||
}}
|
||||
/>
|
||||
{fidelity && (
|
||||
<MetadataItem
|
||||
label="Fidelity"
|
||||
value={fidelity}
|
||||
onClick={() => {
|
||||
dispatch(setCodeformerFidelity(fidelity));
|
||||
dispatch(setFacetoolType('codeformer'));
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
}
|
||||
)}
|
||||
|
@ -6,21 +6,21 @@ import {
|
||||
useAppSelector,
|
||||
} from '../../../../app/store';
|
||||
import IAISwitch from '../../../../common/components/IAISwitch';
|
||||
import { setShouldRunGFPGAN } from '../../optionsSlice';
|
||||
import { setShouldRunFacetool } from '../../optionsSlice';
|
||||
|
||||
export default function FaceRestore() {
|
||||
const isGFPGANAvailable = useAppSelector(
|
||||
(state: RootState) => state.system.isGFPGANAvailable
|
||||
);
|
||||
|
||||
const shouldRunGFPGAN = useAppSelector(
|
||||
(state: RootState) => state.options.shouldRunGFPGAN
|
||||
const shouldRunFacetool = useAppSelector(
|
||||
(state: RootState) => state.options.shouldRunFacetool
|
||||
);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const handleChangeShouldRunGFPGAN = (e: ChangeEvent<HTMLInputElement>) =>
|
||||
dispatch(setShouldRunGFPGAN(e.target.checked));
|
||||
const handleChangeShouldRunFacetool = (e: ChangeEvent<HTMLInputElement>) =>
|
||||
dispatch(setShouldRunFacetool(e.target.checked));
|
||||
|
||||
return (
|
||||
<Flex
|
||||
@ -32,8 +32,8 @@ export default function FaceRestore() {
|
||||
<p>Restore Face</p>
|
||||
<IAISwitch
|
||||
isDisabled={!isGFPGANAvailable}
|
||||
isChecked={shouldRunGFPGAN}
|
||||
onChange={handleChangeShouldRunGFPGAN}
|
||||
isChecked={shouldRunFacetool}
|
||||
onChange={handleChangeShouldRunFacetool}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
|
@ -3,18 +3,29 @@ import { Flex } from '@chakra-ui/react';
|
||||
import { RootState } from '../../../../app/store';
|
||||
import { useAppDispatch, useAppSelector } from '../../../../app/store';
|
||||
|
||||
import { OptionsState, setGfpganStrength } from '../../optionsSlice';
|
||||
import {
|
||||
FacetoolType,
|
||||
OptionsState,
|
||||
setCodeformerFidelity,
|
||||
setFacetoolStrength,
|
||||
setFacetoolType,
|
||||
} from '../../optionsSlice';
|
||||
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { isEqual } from 'lodash';
|
||||
import { SystemState } from '../../../system/systemSlice';
|
||||
import IAINumberInput from '../../../../common/components/IAINumberInput';
|
||||
import IAISelect from '../../../../common/components/IAISelect';
|
||||
import { FACETOOL_TYPES } from '../../../../app/constants';
|
||||
import { ChangeEvent } from 'react';
|
||||
|
||||
const optionsSelector = createSelector(
|
||||
(state: RootState) => state.options,
|
||||
(options: OptionsState) => {
|
||||
return {
|
||||
gfpganStrength: options.gfpganStrength,
|
||||
facetoolStrength: options.facetoolStrength,
|
||||
facetoolType: options.facetoolType,
|
||||
codeformerFidelity: options.codeformerFidelity,
|
||||
};
|
||||
},
|
||||
{
|
||||
@ -43,13 +54,26 @@ const systemSelector = createSelector(
|
||||
*/
|
||||
const FaceRestoreOptions = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { gfpganStrength } = useAppSelector(optionsSelector);
|
||||
const { facetoolStrength, facetoolType, codeformerFidelity } =
|
||||
useAppSelector(optionsSelector);
|
||||
const { isGFPGANAvailable } = useAppSelector(systemSelector);
|
||||
|
||||
const handleChangeStrength = (v: number) => dispatch(setGfpganStrength(v));
|
||||
const handleChangeStrength = (v: number) => dispatch(setFacetoolStrength(v));
|
||||
|
||||
const handleChangeCodeformerFidelity = (v: number) =>
|
||||
dispatch(setCodeformerFidelity(v));
|
||||
|
||||
const handleChangeFacetoolType = (e: ChangeEvent<HTMLSelectElement>) =>
|
||||
dispatch(setFacetoolType(e.target.value as FacetoolType));
|
||||
|
||||
return (
|
||||
<Flex direction={'column'} gap={2}>
|
||||
<IAISelect
|
||||
label="Type"
|
||||
validValues={FACETOOL_TYPES.concat()}
|
||||
value={facetoolType}
|
||||
onChange={handleChangeFacetoolType}
|
||||
/>
|
||||
<IAINumberInput
|
||||
isDisabled={!isGFPGANAvailable}
|
||||
label="Strength"
|
||||
@ -57,10 +81,23 @@ const FaceRestoreOptions = () => {
|
||||
min={0}
|
||||
max={1}
|
||||
onChange={handleChangeStrength}
|
||||
value={gfpganStrength}
|
||||
value={facetoolStrength}
|
||||
width="90px"
|
||||
isInteger={false}
|
||||
/>
|
||||
{facetoolType === 'codeformer' && (
|
||||
<IAINumberInput
|
||||
isDisabled={!isGFPGANAvailable}
|
||||
label="Fidelity"
|
||||
step={0.05}
|
||||
min={0}
|
||||
max={1}
|
||||
onChange={handleChangeCodeformerFidelity}
|
||||
value={codeformerFidelity}
|
||||
width="90px"
|
||||
isInteger={false}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@ -3,9 +3,12 @@ import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import * as InvokeAI from '../../app/invokeai';
|
||||
import promptToString from '../../common/util/promptToString';
|
||||
import { seedWeightsToString } from '../../common/util/seedWeightPairs';
|
||||
import { FACETOOL_TYPES } from '../../app/constants';
|
||||
|
||||
export type UpscalingLevel = 2 | 4;
|
||||
|
||||
export type FacetoolType = typeof FACETOOL_TYPES[number];
|
||||
|
||||
export interface OptionsState {
|
||||
prompt: string;
|
||||
iterations: number;
|
||||
@ -18,7 +21,9 @@ export interface OptionsState {
|
||||
perlin: number;
|
||||
seed: number;
|
||||
img2imgStrength: number;
|
||||
gfpganStrength: number;
|
||||
facetoolType: FacetoolType;
|
||||
facetoolStrength: number;
|
||||
codeformerFidelity: number;
|
||||
upscalingLevel: UpscalingLevel;
|
||||
upscalingStrength: number;
|
||||
shouldUseInitImage: boolean;
|
||||
@ -31,7 +36,7 @@ export interface OptionsState {
|
||||
variationAmount: number;
|
||||
seedWeights: string;
|
||||
shouldRunESRGAN: boolean;
|
||||
shouldRunGFPGAN: boolean;
|
||||
shouldRunFacetool: boolean;
|
||||
shouldRandomizeSeed: boolean;
|
||||
showAdvancedOptions: boolean;
|
||||
activeTab: number;
|
||||
@ -63,8 +68,10 @@ const initialOptionsState: OptionsState = {
|
||||
shouldRunESRGAN: false,
|
||||
upscalingLevel: 4,
|
||||
upscalingStrength: 0.75,
|
||||
shouldRunGFPGAN: false,
|
||||
gfpganStrength: 0.8,
|
||||
shouldRunFacetool: false,
|
||||
facetoolStrength: 0.8,
|
||||
facetoolType: 'gfpgan',
|
||||
codeformerFidelity: 0.75,
|
||||
shouldRandomizeSeed: true,
|
||||
showAdvancedOptions: true,
|
||||
activeTab: 0,
|
||||
@ -117,8 +124,11 @@ export const optionsSlice = createSlice({
|
||||
setImg2imgStrength: (state, action: PayloadAction<number>) => {
|
||||
state.img2imgStrength = action.payload;
|
||||
},
|
||||
setGfpganStrength: (state, action: PayloadAction<number>) => {
|
||||
state.gfpganStrength = action.payload;
|
||||
setFacetoolStrength: (state, action: PayloadAction<number>) => {
|
||||
state.facetoolStrength = action.payload;
|
||||
},
|
||||
setCodeformerFidelity: (state, action: PayloadAction<number>) => {
|
||||
state.codeformerFidelity = action.payload;
|
||||
},
|
||||
setUpscalingLevel: (state, action: PayloadAction<UpscalingLevel>) => {
|
||||
state.upscalingLevel = action.payload;
|
||||
@ -229,8 +239,8 @@ export const optionsSlice = createSlice({
|
||||
// (postprocess: InvokeAI.PostProcessedImageMetadata) => {
|
||||
// if (postprocess.type === 'gfpgan') {
|
||||
// const { strength } = postprocess;
|
||||
// if (strength) state.gfpganStrength = strength;
|
||||
// state.shouldRunGFPGAN = true;
|
||||
// if (strength) state.facetoolStrength = strength;
|
||||
// state.shouldRunFacetool = true;
|
||||
// postprocessingNotDone = postprocessingNotDone.filter(
|
||||
// (p) => p !== 'gfpgan'
|
||||
// );
|
||||
@ -250,7 +260,7 @@ export const optionsSlice = createSlice({
|
||||
|
||||
// postprocessingNotDone.forEach((p) => {
|
||||
// if (p === 'esrgan') state.shouldRunESRGAN = false;
|
||||
// if (p === 'gfpgan') state.shouldRunGFPGAN = false;
|
||||
// if (p === 'gfpgan') state.shouldRunFacetool = false;
|
||||
// });
|
||||
|
||||
if (prompt) state.prompt = promptToString(prompt);
|
||||
@ -260,7 +270,7 @@ export const optionsSlice = createSlice({
|
||||
if (threshold) state.threshold = threshold;
|
||||
if (typeof threshold === 'undefined') state.threshold = 0;
|
||||
if (perlin) state.perlin = perlin;
|
||||
if (typeof perlin === 'undefined') state.perlin = 0;
|
||||
if (typeof perlin === 'undefined') state.perlin = 0;
|
||||
if (typeof seamless === 'boolean') state.seamless = seamless;
|
||||
if (typeof hires_fix === 'boolean') state.hiresFix = hires_fix;
|
||||
if (width) state.width = width;
|
||||
@ -272,8 +282,11 @@ export const optionsSlice = createSlice({
|
||||
...initialOptionsState,
|
||||
};
|
||||
},
|
||||
setShouldRunGFPGAN: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldRunGFPGAN = action.payload;
|
||||
setShouldRunFacetool: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldRunFacetool = action.payload;
|
||||
},
|
||||
setFacetoolType: (state, action: PayloadAction<FacetoolType>) => {
|
||||
state.facetoolType = action.payload;
|
||||
},
|
||||
setShouldRunESRGAN: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldRunESRGAN = action.payload;
|
||||
@ -310,7 +323,9 @@ export const {
|
||||
setSeamless,
|
||||
setHiresFix,
|
||||
setImg2imgStrength,
|
||||
setGfpganStrength,
|
||||
setFacetoolStrength,
|
||||
setFacetoolType,
|
||||
setCodeformerFidelity,
|
||||
setUpscalingLevel,
|
||||
setUpscalingStrength,
|
||||
setShouldUseInitImage,
|
||||
@ -324,7 +339,7 @@ export const {
|
||||
setSeedWeights,
|
||||
setVariationAmount,
|
||||
setAllParameters,
|
||||
setShouldRunGFPGAN,
|
||||
setShouldRunFacetool,
|
||||
setShouldRunESRGAN,
|
||||
setShouldRandomizeSeed,
|
||||
setShowAdvancedOptions,
|
||||
|
Loading…
Reference in New Issue
Block a user