feat: Add Paste / Mask Blur / Color Correction to Inpainting

Seam options are now removed. They are replaced by two options --Mask Blur and Mask Blur Method .. which control the softness of the mask that is being painted.
This commit is contained in:
blessedcoolant
2023-08-12 03:28:19 +12:00
parent 69a9dc7b36
commit 1affb7f647
11 changed files with 147 additions and 155 deletions

View File

@ -0,0 +1,21 @@
import { Flex } from '@chakra-ui/react';
import IAICollapse from 'common/components/IAICollapse';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import ParamMaskBlur from './ParamMaskBlur';
import ParamMaskBlurMethod from './ParamMaskBlurMethod';
const ParamMaskAdjustmentCollapse = () => {
const { t } = useTranslation();
return (
<IAICollapse label={t('parameters.maskAdjustmentsHeader')}>
<Flex sx={{ flexDirection: 'column', gap: 2 }}>
<ParamMaskBlur />
<ParamMaskBlurMethod />
</Flex>
</IAICollapse>
);
};
export default memo(ParamMaskAdjustmentCollapse);

View File

@ -1,31 +1,31 @@
import type { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISlider from 'common/components/IAISlider';
import { setSeamBlur } from 'features/parameters/store/generationSlice';
import { setMaskBlur } from 'features/parameters/store/generationSlice';
import { useTranslation } from 'react-i18next';
export default function ParamSeamBlur() {
export default function ParamMaskBlur() {
const dispatch = useAppDispatch();
const seamBlur = useAppSelector(
(state: RootState) => state.generation.seamBlur
const maskBlur = useAppSelector(
(state: RootState) => state.generation.maskBlur
);
const { t } = useTranslation();
return (
<IAISlider
label={t('parameters.seamBlur')}
label={t('parameters.maskBlur')}
min={0}
max={64}
sliderNumberInputProps={{ max: 512 }}
value={seamBlur}
value={maskBlur}
onChange={(v) => {
dispatch(setSeamBlur(v));
dispatch(setMaskBlur(v));
}}
withInput
withSliderMarks
withReset
handleReset={() => {
dispatch(setSeamBlur(16));
dispatch(setMaskBlur(16));
}}
/>
);

View File

@ -0,0 +1,36 @@
import { SelectItem } from '@mantine/core';
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIMantineSelect from 'common/components/IAIMantineSelect';
import { setMaskBlurMethod } from 'features/parameters/store/generationSlice';
import { useTranslation } from 'react-i18next';
export type MaskBlurMethods = 'box' | 'gaussian';
const maskBlurMethods: SelectItem[] = [
{ label: 'Box Blur', value: 'box' },
{ label: 'Gaussian Blur', value: 'gaussian' },
];
export default function ParamMaskBlurMethod() {
const maskBlurMethod = useAppSelector(
(state: RootState) => state.generation.maskBlurMethod
);
const dispatch = useAppDispatch();
const { t } = useTranslation();
const handleMaskBlurMethodChange = (v: string | null) => {
if (!v) return;
dispatch(setMaskBlurMethod(v as MaskBlurMethods));
};
return (
<IAIMantineSelect
value={maskBlurMethod}
onChange={handleMaskBlurMethodChange}
label={t('parameters.maskBlurMethod')}
data={maskBlurMethods}
/>
);
}

View File

@ -1,22 +0,0 @@
import IAICollapse from 'common/components/IAICollapse';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import ParamSeamBlur from './ParamSeamBlur';
import ParamSeamSize from './ParamSeamSize';
import ParamSeamSteps from './ParamSeamSteps';
import ParamSeamStrength from './ParamSeamStrength';
const ParamSeamCorrectionCollapse = () => {
const { t } = useTranslation();
return (
<IAICollapse label={t('parameters.seamCorrectionHeader')}>
<ParamSeamSize />
<ParamSeamBlur />
<ParamSeamStrength />
<ParamSeamSteps />
</IAICollapse>
);
};
export default memo(ParamSeamCorrectionCollapse);

View File

@ -1,31 +0,0 @@
import type { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISlider from 'common/components/IAISlider';
import { setSeamSize } from 'features/parameters/store/generationSlice';
import { useTranslation } from 'react-i18next';
export default function ParamSeamSize() {
const dispatch = useAppDispatch();
const { t } = useTranslation();
const seamSize = useAppSelector(
(state: RootState) => state.generation.seamSize
);
return (
<IAISlider
label={t('parameters.seamSize')}
min={1}
max={256}
sliderNumberInputProps={{ max: 512 }}
value={seamSize}
onChange={(v) => {
dispatch(setSeamSize(v));
}}
withInput
withSliderMarks
withReset
handleReset={() => dispatch(setSeamSize(96))}
/>
);
}

View File

@ -1,32 +0,0 @@
import type { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISlider from 'common/components/IAISlider';
import { setSeamSteps } from 'features/parameters/store/generationSlice';
import { useTranslation } from 'react-i18next';
export default function ParamSeamSteps() {
const { t } = useTranslation();
const seamSteps = useAppSelector(
(state: RootState) => state.generation.seamSteps
);
const dispatch = useAppDispatch();
return (
<IAISlider
label={t('parameters.seamSteps')}
min={1}
max={100}
sliderNumberInputProps={{ max: 999 }}
value={seamSteps}
onChange={(v) => {
dispatch(setSeamSteps(v));
}}
withInput
withSliderMarks
withReset
handleReset={() => {
dispatch(setSeamSteps(30));
}}
/>
);
}

View File

@ -1,32 +0,0 @@
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISlider from 'common/components/IAISlider';
import { setSeamStrength } from 'features/parameters/store/generationSlice';
import { useTranslation } from 'react-i18next';
export default function ParamSeamStrength() {
const dispatch = useAppDispatch();
const { t } = useTranslation();
const seamStrength = useAppSelector(
(state: RootState) => state.generation.seamStrength
);
return (
<IAISlider
label={t('parameters.seamStrength')}
min={0.01}
max={0.99}
step={0.01}
value={seamStrength}
onChange={(v) => {
dispatch(setSeamStrength(v));
}}
withInput
withSliderMarks
withReset
handleReset={() => {
dispatch(setSeamStrength(0.7));
}}
/>
);
}

View File

@ -4,6 +4,7 @@ import { roundToMultiple } from 'common/util/roundDownToMultiple';
import { configChanged } from 'features/system/store/configSlice';
import { clamp } from 'lodash-es';
import { ImageDTO } from 'services/api/types';
import { MaskBlurMethods } from '../components/Parameters/Canvas/MaskAdjustment/ParamMaskBlurMethod';
import { clipSkipMap } from '../types/constants';
import {
CfgScaleParam,
@ -33,10 +34,8 @@ export interface GenerationState {
positivePrompt: PositivePromptParam;
negativePrompt: NegativePromptParam;
scheduler: SchedulerParam;
seamBlur: number;
seamSize: number;
seamSteps: number;
seamStrength: number;
maskBlur: number;
maskBlurMethod: MaskBlurMethods;
seed: SeedParam;
seedWeights: string;
shouldFitToWidthHeight: boolean;
@ -72,10 +71,8 @@ export const initialGenerationState: GenerationState = {
positivePrompt: '',
negativePrompt: '',
scheduler: 'euler',
seamBlur: 16,
seamSize: 96,
seamSteps: 30,
seamStrength: 0.7,
maskBlur: 16,
maskBlurMethod: 'box',
seed: 0,
seedWeights: '',
shouldFitToWidthHeight: true,
@ -196,17 +193,11 @@ export const generationSlice = createSlice({
clearInitialImage: (state) => {
state.initialImage = undefined;
},
setSeamSize: (state, action: PayloadAction<number>) => {
state.seamSize = action.payload;
setMaskBlur: (state, action: PayloadAction<number>) => {
state.maskBlur = action.payload;
},
setSeamBlur: (state, action: PayloadAction<number>) => {
state.seamBlur = action.payload;
},
setSeamStrength: (state, action: PayloadAction<number>) => {
state.seamStrength = action.payload;
},
setSeamSteps: (state, action: PayloadAction<number>) => {
state.seamSteps = action.payload;
setMaskBlurMethod: (state, action: PayloadAction<MaskBlurMethods>) => {
state.maskBlurMethod = action.payload;
},
setTileSize: (state, action: PayloadAction<number>) => {
state.tileSize = action.payload;
@ -312,10 +303,8 @@ export const {
setPositivePrompt,
setNegativePrompt,
setScheduler,
setSeamBlur,
setSeamSize,
setSeamSteps,
setSeamStrength,
setMaskBlur,
setMaskBlurMethod,
setSeed,
setSeedWeights,
setShouldFitToWidthHeight,