mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
ui: Color Infill UI
This commit is contained in:
parent
adb7966bb3
commit
e55ab5b3a1
@ -891,6 +891,7 @@
|
|||||||
"infillMosaicTileHeight": "Tile Height",
|
"infillMosaicTileHeight": "Tile Height",
|
||||||
"infillMosaicMinColor": "Min Color",
|
"infillMosaicMinColor": "Min Color",
|
||||||
"infillMosaicMaxColor": "Max Color",
|
"infillMosaicMaxColor": "Max Color",
|
||||||
|
"infillColorValue": "Fill Color",
|
||||||
"info": "Info",
|
"info": "Info",
|
||||||
"invoke": {
|
"invoke": {
|
||||||
"addingImagesTo": "Adding images to",
|
"addingImagesTo": "Adding images to",
|
||||||
|
@ -69,6 +69,7 @@ export const buildCanvasOutpaintGraph = async (
|
|||||||
infillMosaicTileHeight,
|
infillMosaicTileHeight,
|
||||||
infillMosaicMinColor,
|
infillMosaicMinColor,
|
||||||
infillMosaicMaxColor,
|
infillMosaicMaxColor,
|
||||||
|
infillColorValue,
|
||||||
clipSkip,
|
clipSkip,
|
||||||
seamlessXAxis,
|
seamlessXAxis,
|
||||||
seamlessYAxis,
|
seamlessYAxis,
|
||||||
@ -376,6 +377,7 @@ export const buildCanvasOutpaintGraph = async (
|
|||||||
graph.nodes[INPAINT_INFILL] = {
|
graph.nodes[INPAINT_INFILL] = {
|
||||||
type: 'infill_rgba',
|
type: 'infill_rgba',
|
||||||
id: INPAINT_INFILL,
|
id: INPAINT_INFILL,
|
||||||
|
color: infillColorValue,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,7 @@ export const buildCanvasSDXLOutpaintGraph = async (
|
|||||||
infillMosaicTileHeight,
|
infillMosaicTileHeight,
|
||||||
infillMosaicMinColor,
|
infillMosaicMinColor,
|
||||||
infillMosaicMaxColor,
|
infillMosaicMaxColor,
|
||||||
|
infillColorValue,
|
||||||
seamlessXAxis,
|
seamlessXAxis,
|
||||||
seamlessYAxis,
|
seamlessYAxis,
|
||||||
canvasCoherenceMode,
|
canvasCoherenceMode,
|
||||||
@ -386,6 +387,7 @@ export const buildCanvasSDXLOutpaintGraph = async (
|
|||||||
type: 'infill_rgba',
|
type: 'infill_rgba',
|
||||||
id: INPAINT_INFILL,
|
id: INPAINT_INFILL,
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
|
color: infillColorValue,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
import { Box, Flex, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||||
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import IAIColorPicker from 'common/components/IAIColorPicker';
|
||||||
|
import { selectGenerationSlice, setInfillColorValue } from 'features/parameters/store/generationSlice';
|
||||||
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
|
import type { RgbaColor } from 'react-colorful';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
const ParamInfillColorOptions = () => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const selector = useMemo(
|
||||||
|
() =>
|
||||||
|
createSelector(selectGenerationSlice, (generation) => ({
|
||||||
|
infillColor: generation.infillColorValue,
|
||||||
|
})),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const { infillColor } = useAppSelector(selector);
|
||||||
|
|
||||||
|
const infillMethod = useAppSelector((s) => s.generation.infillMethod);
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const handleInfillColor = useCallback(
|
||||||
|
(v: RgbaColor) => {
|
||||||
|
dispatch(setInfillColorValue(v));
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex flexDir="column" gap={4}>
|
||||||
|
<FormControl isDisabled={infillMethod !== 'color'}>
|
||||||
|
<FormLabel>{t('parameters.infillColorValue')}</FormLabel>
|
||||||
|
<Box w="full" pt={2} pb={2}>
|
||||||
|
<IAIColorPicker color={infillColor} onChange={handleInfillColor} />
|
||||||
|
</Box>
|
||||||
|
</FormControl>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(ParamInfillColorOptions);
|
@ -13,7 +13,7 @@ import { memo, useCallback, useMemo } from 'react';
|
|||||||
import type { RgbaColor } from 'react-colorful';
|
import type { RgbaColor } from 'react-colorful';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const ParamMosaicInfillTileSize = () => {
|
const ParamInfillMosaicTileSize = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
@ -124,4 +124,4 @@ const ParamMosaicInfillTileSize = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(ParamMosaicInfillTileSize);
|
export default memo(ParamInfillMosaicTileSize);
|
@ -1,9 +1,10 @@
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
|
import ParamInfillColorOptions from './ParamInfillColorOptions';
|
||||||
|
import ParamInfillMosaicOptions from './ParamInfillMosaicOptions';
|
||||||
import ParamInfillPatchmatchDownscaleSize from './ParamInfillPatchmatchDownscaleSize';
|
import ParamInfillPatchmatchDownscaleSize from './ParamInfillPatchmatchDownscaleSize';
|
||||||
import ParamInfillTilesize from './ParamInfillTilesize';
|
import ParamInfillTilesize from './ParamInfillTilesize';
|
||||||
import ParamMosaicInfillOptions from './ParamMosaicInfillOptions';
|
|
||||||
|
|
||||||
const ParamInfillOptions = () => {
|
const ParamInfillOptions = () => {
|
||||||
const infillMethod = useAppSelector((s) => s.generation.infillMethod);
|
const infillMethod = useAppSelector((s) => s.generation.infillMethod);
|
||||||
@ -16,7 +17,11 @@ const ParamInfillOptions = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (infillMethod === 'mosaic') {
|
if (infillMethod === 'mosaic') {
|
||||||
return <ParamMosaicInfillOptions />;
|
return <ParamInfillMosaicOptions />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (infillMethod === 'color') {
|
||||||
|
return <ParamInfillColorOptions />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -44,8 +44,6 @@ const initialGenerationState: GenerationState = {
|
|||||||
shouldFitToWidthHeight: true,
|
shouldFitToWidthHeight: true,
|
||||||
shouldRandomizeSeed: true,
|
shouldRandomizeSeed: true,
|
||||||
steps: 50,
|
steps: 50,
|
||||||
infillTileSize: 32,
|
|
||||||
infillPatchmatchDownscaleSize: 1,
|
|
||||||
width: 512,
|
width: 512,
|
||||||
model: null,
|
model: null,
|
||||||
vae: null,
|
vae: null,
|
||||||
@ -56,10 +54,13 @@ const initialGenerationState: GenerationState = {
|
|||||||
shouldUseCpuNoise: true,
|
shouldUseCpuNoise: true,
|
||||||
shouldShowAdvancedOptions: false,
|
shouldShowAdvancedOptions: false,
|
||||||
aspectRatio: { ...initialAspectRatioState },
|
aspectRatio: { ...initialAspectRatioState },
|
||||||
|
infillTileSize: 32,
|
||||||
|
infillPatchmatchDownscaleSize: 1,
|
||||||
infillMosaicTileWidth: 64,
|
infillMosaicTileWidth: 64,
|
||||||
infillMosaicTileHeight: 64,
|
infillMosaicTileHeight: 64,
|
||||||
infillMosaicMinColor: { r: 0, g: 0, b: 0, a: 1 },
|
infillMosaicMinColor: { r: 0, g: 0, b: 0, a: 1 },
|
||||||
infillMosaicMaxColor: { r: 255, g: 255, b: 255, a: 1 },
|
infillMosaicMaxColor: { r: 255, g: 255, b: 255, a: 1 },
|
||||||
|
infillColorValue: { r: 0, g: 0, b: 0, a: 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
export const generationSlice = createSlice({
|
export const generationSlice = createSlice({
|
||||||
@ -121,15 +122,6 @@ export const generationSlice = createSlice({
|
|||||||
setCanvasCoherenceMinDenoise: (state, action: PayloadAction<number>) => {
|
setCanvasCoherenceMinDenoise: (state, action: PayloadAction<number>) => {
|
||||||
state.canvasCoherenceMinDenoise = action.payload;
|
state.canvasCoherenceMinDenoise = action.payload;
|
||||||
},
|
},
|
||||||
setInfillMethod: (state, action: PayloadAction<string>) => {
|
|
||||||
state.infillMethod = action.payload;
|
|
||||||
},
|
|
||||||
setInfillTileSize: (state, action: PayloadAction<number>) => {
|
|
||||||
state.infillTileSize = action.payload;
|
|
||||||
},
|
|
||||||
setInfillPatchmatchDownscaleSize: (state, action: PayloadAction<number>) => {
|
|
||||||
state.infillPatchmatchDownscaleSize = action.payload;
|
|
||||||
},
|
|
||||||
initialImageChanged: (state, action: PayloadAction<ImageDTO>) => {
|
initialImageChanged: (state, action: PayloadAction<ImageDTO>) => {
|
||||||
const { image_name, width, height } = action.payload;
|
const { image_name, width, height } = action.payload;
|
||||||
state.initialImage = { imageName: image_name, width, height };
|
state.initialImage = { imageName: image_name, width, height };
|
||||||
@ -211,6 +203,15 @@ export const generationSlice = createSlice({
|
|||||||
aspectRatioChanged: (state, action: PayloadAction<AspectRatioState>) => {
|
aspectRatioChanged: (state, action: PayloadAction<AspectRatioState>) => {
|
||||||
state.aspectRatio = action.payload;
|
state.aspectRatio = action.payload;
|
||||||
},
|
},
|
||||||
|
setInfillMethod: (state, action: PayloadAction<string>) => {
|
||||||
|
state.infillMethod = action.payload;
|
||||||
|
},
|
||||||
|
setInfillTileSize: (state, action: PayloadAction<number>) => {
|
||||||
|
state.infillTileSize = action.payload;
|
||||||
|
},
|
||||||
|
setInfillPatchmatchDownscaleSize: (state, action: PayloadAction<number>) => {
|
||||||
|
state.infillPatchmatchDownscaleSize = action.payload;
|
||||||
|
},
|
||||||
setInfillMosaicTileWidth: (state, action: PayloadAction<number>) => {
|
setInfillMosaicTileWidth: (state, action: PayloadAction<number>) => {
|
||||||
state.infillMosaicTileWidth = action.payload;
|
state.infillMosaicTileWidth = action.payload;
|
||||||
},
|
},
|
||||||
@ -223,6 +224,9 @@ export const generationSlice = createSlice({
|
|||||||
setInfillMosaicMaxColor: (state, action: PayloadAction<RgbaColor>) => {
|
setInfillMosaicMaxColor: (state, action: PayloadAction<RgbaColor>) => {
|
||||||
state.infillMosaicMaxColor = action.payload;
|
state.infillMosaicMaxColor = action.payload;
|
||||||
},
|
},
|
||||||
|
setInfillColorValue: (state, action: PayloadAction<RgbaColor>) => {
|
||||||
|
state.infillColorValue = action.payload;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
extraReducers: (builder) => {
|
extraReducers: (builder) => {
|
||||||
builder.addCase(configChanged, (state, action) => {
|
builder.addCase(configChanged, (state, action) => {
|
||||||
@ -266,8 +270,6 @@ export const {
|
|||||||
setShouldFitToWidthHeight,
|
setShouldFitToWidthHeight,
|
||||||
setShouldRandomizeSeed,
|
setShouldRandomizeSeed,
|
||||||
setSteps,
|
setSteps,
|
||||||
setInfillTileSize,
|
|
||||||
setInfillPatchmatchDownscaleSize,
|
|
||||||
initialImageChanged,
|
initialImageChanged,
|
||||||
modelChanged,
|
modelChanged,
|
||||||
vaeSelected,
|
vaeSelected,
|
||||||
@ -281,10 +283,13 @@ export const {
|
|||||||
heightChanged,
|
heightChanged,
|
||||||
widthRecalled,
|
widthRecalled,
|
||||||
heightRecalled,
|
heightRecalled,
|
||||||
|
setInfillTileSize,
|
||||||
|
setInfillPatchmatchDownscaleSize,
|
||||||
setInfillMosaicTileWidth,
|
setInfillMosaicTileWidth,
|
||||||
setInfillMosaicTileHeight,
|
setInfillMosaicTileHeight,
|
||||||
setInfillMosaicMinColor,
|
setInfillMosaicMinColor,
|
||||||
setInfillMosaicMaxColor,
|
setInfillMosaicMaxColor,
|
||||||
|
setInfillColorValue,
|
||||||
} = generationSlice.actions;
|
} = generationSlice.actions;
|
||||||
|
|
||||||
export const { selectOptimalDimension } = generationSlice.selectors;
|
export const { selectOptimalDimension } = generationSlice.selectors;
|
||||||
|
@ -40,8 +40,6 @@ export interface GenerationState {
|
|||||||
shouldFitToWidthHeight: boolean;
|
shouldFitToWidthHeight: boolean;
|
||||||
shouldRandomizeSeed: boolean;
|
shouldRandomizeSeed: boolean;
|
||||||
steps: ParameterSteps;
|
steps: ParameterSteps;
|
||||||
infillTileSize: number;
|
|
||||||
infillPatchmatchDownscaleSize: number;
|
|
||||||
width: ParameterWidth;
|
width: ParameterWidth;
|
||||||
model: ParameterModel | null;
|
model: ParameterModel | null;
|
||||||
vae: ParameterVAEModel | null;
|
vae: ParameterVAEModel | null;
|
||||||
@ -52,10 +50,13 @@ export interface GenerationState {
|
|||||||
shouldUseCpuNoise: boolean;
|
shouldUseCpuNoise: boolean;
|
||||||
shouldShowAdvancedOptions: boolean;
|
shouldShowAdvancedOptions: boolean;
|
||||||
aspectRatio: AspectRatioState;
|
aspectRatio: AspectRatioState;
|
||||||
|
infillTileSize: number;
|
||||||
|
infillPatchmatchDownscaleSize: number;
|
||||||
infillMosaicTileWidth: number;
|
infillMosaicTileWidth: number;
|
||||||
infillMosaicTileHeight: number;
|
infillMosaicTileHeight: number;
|
||||||
infillMosaicMinColor: RgbaColor;
|
infillMosaicMinColor: RgbaColor;
|
||||||
infillMosaicMaxColor: RgbaColor;
|
infillMosaicMaxColor: RgbaColor;
|
||||||
|
infillColorValue: RgbaColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PayloadActionWithOptimalDimension<T = void> = PayloadAction<T, string, { optimalDimension: number }>;
|
export type PayloadActionWithOptimalDimension<T = void> = PayloadAction<T, string, { optimalDimension: number }>;
|
||||||
|
Loading…
Reference in New Issue
Block a user