Adds infill method

This commit is contained in:
psychedelicious 2022-11-22 14:52:54 +11:00 committed by blessedcoolant
parent ddfd82559f
commit 723dcf4236
7 changed files with 66 additions and 25 deletions

View File

@ -21,6 +21,7 @@ from threading import Event
from ldm.invoke.args import Args, APP_ID, APP_VERSION, calculate_init_img_hash from ldm.invoke.args import Args, APP_ID, APP_VERSION, calculate_init_img_hash
from ldm.invoke.pngwriter import PngWriter, retrieve_metadata from ldm.invoke.pngwriter import PngWriter, retrieve_metadata
from ldm.invoke.prompt_parser import split_weighted_subprompts from ldm.invoke.prompt_parser import split_weighted_subprompts
from ldm.invoke.generator.inpaint import infill_methods
from backend.modules.parameters import parameters_to_command from backend.modules.parameters import parameters_to_command
from backend.modules.get_canvas_generation_mode import ( from backend.modules.get_canvas_generation_mode import (
@ -286,6 +287,7 @@ class InvokeAIWebServer:
print(f">> System config requested") print(f">> System config requested")
config = self.get_system_config() config = self.get_system_config()
config["model_list"] = self.generate.model_cache.list_models() config["model_list"] = self.generate.model_cache.list_models()
config["infill_methods"] = infill_methods
socketio.emit("systemConfig", config) socketio.emit("systemConfig", config)
@socketio.on("requestModelChange") @socketio.on("requestModelChange")
@ -821,6 +823,7 @@ class InvokeAIWebServer:
generation_parameters.pop("seam_steps", None) generation_parameters.pop("seam_steps", None)
generation_parameters.pop("tile_size", None) generation_parameters.pop("tile_size", None)
generation_parameters.pop("force_outpaint", None) generation_parameters.pop("force_outpaint", None)
generation_parameters.pop("infill_method", None)
elif actual_generation_mode == "txt2img": elif actual_generation_mode == "txt2img":
generation_parameters["height"] = original_bounding_box["height"] generation_parameters["height"] = original_bounding_box["height"]
generation_parameters["width"] = original_bounding_box["width"] generation_parameters["width"] = original_bounding_box["width"]
@ -834,6 +837,7 @@ class InvokeAIWebServer:
generation_parameters.pop("seam_steps", None) generation_parameters.pop("seam_steps", None)
generation_parameters.pop("tile_size", None) generation_parameters.pop("tile_size", None)
generation_parameters.pop("force_outpaint", None) generation_parameters.pop("force_outpaint", None)
generation_parameters.pop("infill_method", None)
elif generation_parameters["generation_mode"] == "img2img": elif generation_parameters["generation_mode"] == "img2img":
init_img_url = generation_parameters["init_img"] init_img_url = generation_parameters["init_img"]

View File

@ -155,6 +155,7 @@ export declare type SystemGenerationMetadata = {
export declare type SystemConfig = SystemGenerationMetadata & { export declare type SystemConfig = SystemGenerationMetadata & {
model_list: ModelList; model_list: ModelList;
infill_methods: string[];
}; };
export declare type ModelStatus = 'active' | 'cached' | 'not loaded'; export declare type ModelStatus = 'active' | 'cached' | 'not loaded';

View File

@ -29,6 +29,7 @@ import {
import { import {
clearInitialImage, clearInitialImage,
setInfillMethod,
setInitialImage, setInitialImage,
setMaskPath, setMaskPath,
} from 'features/options/store/optionsSlice'; } from 'features/options/store/optionsSlice';
@ -340,6 +341,9 @@ const makeSocketIOListeners = (
}, },
onSystemConfig: (data: InvokeAI.SystemConfig) => { onSystemConfig: (data: InvokeAI.SystemConfig) => {
dispatch(setSystemConfig(data)); dispatch(setSystemConfig(data));
if (!data.infill_methods.includes('patchmatch')) {
dispatch(setInfillMethod(data.infill_methods[0]));
}
}, },
onModelChanged: (data: InvokeAI.ModelChangeResponse) => { onModelChanged: (data: InvokeAI.ModelChangeResponse) => {
const { model_name, model_list } = data; const { model_name, model_list } = data;

View File

@ -46,6 +46,7 @@ export const frontendToBackendParameters = (
height, height,
hiresFix, hiresFix,
img2imgStrength, img2imgStrength,
infillMethod,
initialImage, initialImage,
iterations, iterations,
perlin, perlin,
@ -190,6 +191,7 @@ export const frontendToBackendParameters = (
generationParameters.seam_steps = seamSteps; generationParameters.seam_steps = seamSteps;
generationParameters.tile_size = tileSize; generationParameters.tile_size = tileSize;
generationParameters.force_outpaint = shouldForceOutpaint; generationParameters.force_outpaint = shouldForceOutpaint;
generationParameters.infill_method = infillMethod;
} }
if (shouldGenerateVariations) { if (shouldGenerateVariations) {

View File

@ -1,6 +1,7 @@
import { Box, Flex } from '@chakra-ui/react'; import { Box, Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/store';
import IAISelect from 'common/components/IAISelect';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import IAISwitch from 'common/components/IAISwitch'; import IAISwitch from 'common/components/IAISwitch';
import { optionsSelector } from 'features/options/store/optionsSelectors'; import { optionsSelector } from 'features/options/store/optionsSelectors';
@ -11,28 +12,39 @@ import {
setSeamSteps, setSeamSteps,
setTileSize, setTileSize,
setShouldForceOutpaint, setShouldForceOutpaint,
setInfillMethod,
} from 'features/options/store/optionsSlice'; } from 'features/options/store/optionsSlice';
import { systemSelector } from 'features/system/store/systemSelectors';
import { ChangeEvent } from 'react';
import InpaintReplace from './InpaintReplace'; import InpaintReplace from './InpaintReplace';
const selector = createSelector([optionsSelector], (options) => { const selector = createSelector(
const { [optionsSelector, systemSelector],
seamSize, (options, system) => {
seamBlur, const {
seamStrength, seamSize,
seamSteps, seamBlur,
tileSize, seamStrength,
shouldForceOutpaint, seamSteps,
} = options; tileSize,
shouldForceOutpaint,
infillMethod,
} = options;
return { const { infill_methods: availableInfillMethods } = system;
seamSize,
seamBlur, return {
seamStrength, seamSize,
seamSteps, seamBlur,
tileSize, seamStrength,
shouldForceOutpaint, seamSteps,
}; tileSize,
}); shouldForceOutpaint,
infillMethod,
availableInfillMethods,
};
}
);
const OutpaintingOptions = () => { const OutpaintingOptions = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@ -43,6 +55,8 @@ const OutpaintingOptions = () => {
seamSteps, seamSteps,
tileSize, tileSize,
shouldForceOutpaint, shouldForceOutpaint,
infillMethod,
availableInfillMethods,
} = useAppSelector(selector); } = useAppSelector(selector);
return ( return (
@ -115,7 +129,23 @@ const OutpaintingOptions = () => {
withSliderMarks withSliderMarks
withReset withReset
/> />
<IAISwitch
label={'Force Outpaint'}
isChecked={shouldForceOutpaint}
onChange={(e) => {
dispatch(setShouldForceOutpaint(e.target.checked));
}}
/>
<IAISelect
label="Infill Method"
value={infillMethod}
validValues={availableInfillMethods}
onChange={(e) => dispatch(setInfillMethod(e.target.value))}
/>
<IAISlider <IAISlider
isInputDisabled={infillMethod !== 'tile'}
isResetDisabled={infillMethod !== 'tile'}
isSliderDisabled={infillMethod !== 'tile'}
sliderMarkRightOffset={-4} sliderMarkRightOffset={-4}
label={'Tile Size'} label={'Tile Size'}
min={16} min={16}
@ -132,13 +162,6 @@ const OutpaintingOptions = () => {
withSliderMarks withSliderMarks
withReset withReset
/> />
<IAISwitch
label={'Force Outpaint'}
isChecked={shouldForceOutpaint}
onChange={(e) => {
dispatch(setShouldForceOutpaint(e.target.checked));
}}
/>
</Flex> </Flex>
); );
}; };

View File

@ -20,6 +20,7 @@ export interface OptionsState {
height: number; height: number;
hiresFix: boolean; hiresFix: boolean;
img2imgStrength: number; img2imgStrength: number;
infillMethod: string;
initialImage?: InvokeAI.Image | string; // can be an Image or url initialImage?: InvokeAI.Image | string; // can be an Image or url
isLightBoxOpen: boolean; isLightBoxOpen: boolean;
iterations: number; iterations: number;
@ -67,6 +68,7 @@ const initialOptionsState: OptionsState = {
height: 512, height: 512,
hiresFix: false, hiresFix: false,
img2imgStrength: 0.75, img2imgStrength: 0.75,
infillMethod: 'patchmatch',
isLightBoxOpen: false, isLightBoxOpen: false,
iterations: 1, iterations: 1,
maskPath: '', maskPath: '',
@ -390,6 +392,9 @@ export const optionsSlice = createSlice({
setShouldForceOutpaint: (state, action: PayloadAction<boolean>) => { setShouldForceOutpaint: (state, action: PayloadAction<boolean>) => {
state.shouldForceOutpaint = action.payload; state.shouldForceOutpaint = action.payload;
}, },
setInfillMethod: (state, action: PayloadAction<string>) => {
state.infillMethod = action.payload;
},
}, },
}); });
@ -409,6 +414,7 @@ export const {
setHeight, setHeight,
setHiresFix, setHiresFix,
setImg2imgStrength, setImg2imgStrength,
setInfillMethod,
setInitialImage, setInitialImage,
setIsLightBoxOpen, setIsLightBoxOpen,
setIterations, setIterations,

View File

@ -72,6 +72,7 @@ const initialSystemState: SystemState = {
app_id: '', app_id: '',
app_version: '', app_version: '',
model_list: {}, model_list: {},
infill_methods: [],
hasError: false, hasError: false,
wasErrorSeen: true, wasErrorSeen: true,
isCancelable: true, isCancelable: true,