Fixes: inpainting bug "images do not match"

This commit is contained in:
psychedelicious 2022-10-30 18:07:06 +11:00
parent c0c32d9daa
commit ac1469bbd3
13 changed files with 71 additions and 128 deletions

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>InvokeAI - A Stable Diffusion Toolkit</title> <title>InvokeAI - A Stable Diffusion Toolkit</title>
<link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" /> <link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" />
<script type="module" crossorigin src="./assets/index.1d211108.js"></script> <script type="module" crossorigin src="./assets/index.616d87b3.js"></script>
<link rel="stylesheet" href="./assets/index.64a76932.css"> <link rel="stylesheet" href="./assets/index.64a76932.css">
</head> </head>

View File

@ -269,7 +269,7 @@ const makeSocketIOListeners = (
* Callback to run when we receive a 'imageDeleted' event. * Callback to run when we receive a 'imageDeleted' event.
*/ */
onImageDeleted: (data: InvokeAI.ImageDeletedResponse) => { onImageDeleted: (data: InvokeAI.ImageDeletedResponse) => {
const { url, uuid, category } = data; const { url } = data;
// remove image from gallery // remove image from gallery
dispatch(removeImage(data)); dispatch(removeImage(data));

View File

@ -100,30 +100,15 @@ export const frontendToBackendParameters = (
if (generationMode === 'inpainting' && maskImageElement) { if (generationMode === 'inpainting' && maskImageElement) {
const { const {
lines, lines,
boundingBoxCoordinate: { x, y }, boundingBoxCoordinate,
boundingBoxDimensions: { width, height }, boundingBoxDimensions,
shouldShowBoundingBox,
inpaintReplace, inpaintReplace,
shouldUseInpaintReplace, shouldUseInpaintReplace,
} = inpaintingState; } = inpaintingState;
let bx = x,
by = y,
bwidth = width,
bheight = height;
if (!shouldShowBoundingBox) {
bx = 0;
by = 0;
bwidth = maskImageElement.width;
bheight = maskImageElement.height;
}
const boundingBox = { const boundingBox = {
x: bx, ...boundingBoxCoordinate,
y: by, ...boundingBoxDimensions,
width: bwidth,
height: bheight,
}; };
if (shouldUseInpaintReplace) { if (shouldUseInpaintReplace) {
@ -134,7 +119,7 @@ export const frontendToBackendParameters = (
generationParameters.strength = img2imgStrength; generationParameters.strength = img2imgStrength;
generationParameters.fit = false; generationParameters.fit = false;
const maskDataURL = generateMask(maskImageElement, lines, boundingBox); const maskDataURL = generateMask(maskImageElement, lines);
generationParameters.init_mask = maskDataURL.split( generationParameters.init_mask = maskDataURL.split(
'data:image/png;base64,' 'data:image/png;base64,'

View File

@ -62,11 +62,11 @@ export default function CurrentImagePreview(props: CurrentImagePreviewProps) {
}; };
const handleClickPrevButton = () => { const handleClickPrevButton = () => {
dispatch(selectPrevImage(currentCategory)); dispatch(selectPrevImage());
}; };
const handleClickNextButton = () => { const handleClickNextButton = () => {
dispatch(selectNextImage(currentCategory)); dispatch(selectNextImage());
}; };
return ( return (

View File

@ -147,21 +147,13 @@ export default function ImageGallery() {
[shouldShowGallery] [shouldShowGallery]
); );
useHotkeys( useHotkeys('left', () => {
'left', dispatch(selectPrevImage());
() => { });
dispatch(selectPrevImage(currentCategory));
},
[currentCategory]
);
useHotkeys( useHotkeys('right', () => {
'right', dispatch(selectNextImage());
() => { });
dispatch(selectNextImage(currentCategory));
},
[currentCategory]
);
useHotkeys( useHotkeys(
'shift+p', 'shift+p',

View File

@ -154,8 +154,7 @@ export const gallerySlice = createSlice({
clearIntermediateImage: (state) => { clearIntermediateImage: (state) => {
state.intermediateImage = undefined; state.intermediateImage = undefined;
}, },
selectNextImage: (state, action: PayloadAction<GalleryCategory>) => { selectNextImage: (state) => {
const category = action.payload;
const { currentImage } = state; const { currentImage } = state;
if (!currentImage) return; if (!currentImage) return;
const tempImages = const tempImages =
@ -172,8 +171,7 @@ export const gallerySlice = createSlice({
} }
} }
}, },
selectPrevImage: (state, action: PayloadAction<GalleryCategory>) => { selectPrevImage: (state) => {
const category = action.payload;
const { currentImage } = state; const { currentImage } = state;
if (!currentImage) return; if (!currentImage) return;
const tempImages = const tempImages =

View File

@ -1,7 +1,6 @@
import { Flex } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import _ from 'lodash'; import _ from 'lodash';
import { ChangeEvent } from 'react';
import { BiReset } from 'react-icons/bi'; import { BiReset } from 'react-icons/bi';
import { import {
@ -14,13 +13,11 @@ import IAIIconButton from '../../../../common/components/IAIIconButton';
import IAINumberInput from '../../../../common/components/IAINumberInput'; import IAINumberInput from '../../../../common/components/IAINumberInput';
import IAISlider from '../../../../common/components/IAISlider'; import IAISlider from '../../../../common/components/IAISlider';
import IAISwitch from '../../../../common/components/IAISwitch';
import { roundDownToMultiple } from '../../../../common/util/roundDownToMultiple'; import { roundDownToMultiple } from '../../../../common/util/roundDownToMultiple';
import { import {
InpaintingState, InpaintingState,
setBoundingBoxDimensions, setBoundingBoxDimensions,
setShouldLockBoundingBox, setShouldLockBoundingBox,
setShouldShowBoundingBox,
setShouldShowBoundingBoxFill, setShouldShowBoundingBoxFill,
} from '../../../tabs/Inpainting/inpaintingSlice'; } from '../../../tabs/Inpainting/inpaintingSlice';
@ -30,7 +27,6 @@ const boundingBoxDimensionsSelector = createSelector(
const { const {
canvasDimensions, canvasDimensions,
boundingBoxDimensions, boundingBoxDimensions,
shouldShowBoundingBox,
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
pastLines, pastLines,
futureLines, futureLines,
@ -39,7 +35,6 @@ const boundingBoxDimensionsSelector = createSelector(
return { return {
canvasDimensions, canvasDimensions,
boundingBoxDimensions, boundingBoxDimensions,
shouldShowBoundingBox,
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
pastLines, pastLines,
futureLines, futureLines,
@ -58,22 +53,28 @@ const BoundingBoxSettings = () => {
const { const {
canvasDimensions, canvasDimensions,
boundingBoxDimensions, boundingBoxDimensions,
shouldShowBoundingBox,
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
shouldLockBoundingBox, shouldLockBoundingBox,
} = useAppSelector(boundingBoxDimensionsSelector); } = useAppSelector(boundingBoxDimensionsSelector);
const handleChangeBoundingBoxWidth = (v: number) => { const handleChangeBoundingBoxWidth = (v: number) => {
dispatch(setBoundingBoxDimensions({ ...boundingBoxDimensions, width: Math.floor(v) })); dispatch(
setBoundingBoxDimensions({
...boundingBoxDimensions,
width: Math.floor(v),
})
);
}; };
const handleChangeBoundingBoxHeight = (v: number) => { const handleChangeBoundingBoxHeight = (v: number) => {
dispatch(setBoundingBoxDimensions({ ...boundingBoxDimensions, height: Math.floor(v) })); dispatch(
setBoundingBoxDimensions({
...boundingBoxDimensions,
height: Math.floor(v),
})
);
}; };
const handleShowBoundingBox = (e: ChangeEvent<HTMLInputElement>) =>
dispatch(setShouldShowBoundingBox(e.target.checked));
const handleChangeShouldShowBoundingBoxFill = () => { const handleChangeShouldShowBoundingBoxFill = () => {
dispatch(setShouldShowBoundingBoxFill(!shouldShowBoundingBoxFill)); dispatch(setShouldShowBoundingBoxFill(!shouldShowBoundingBoxFill));
}; };
@ -104,11 +105,6 @@ const BoundingBoxSettings = () => {
<div className="inpainting-bounding-box-settings"> <div className="inpainting-bounding-box-settings">
<div className="inpainting-bounding-box-header"> <div className="inpainting-bounding-box-header">
<p>Inpaint Box</p> <p>Inpaint Box</p>
<IAISwitch
isChecked={shouldShowBoundingBox}
width={'auto'}
onChange={handleShowBoundingBox}
/>
</div> </div>
<div className="inpainting-bounding-box-settings-items"> <div className="inpainting-bounding-box-settings-items">
<div className="inpainting-bounding-box-dimensions-slider-numberinput"> <div className="inpainting-bounding-box-dimensions-slider-numberinput">
@ -119,7 +115,6 @@ const BoundingBoxSettings = () => {
step={64} step={64}
value={boundingBoxDimensions.width} value={boundingBoxDimensions.width}
onChange={handleChangeBoundingBoxWidth} onChange={handleChangeBoundingBoxWidth}
isDisabled={!shouldShowBoundingBox}
width={'5rem'} width={'5rem'}
/> />
<IAINumberInput <IAINumberInput
@ -128,7 +123,6 @@ const BoundingBoxSettings = () => {
min={64} min={64}
max={roundDownToMultiple(canvasDimensions.width, 64)} max={roundDownToMultiple(canvasDimensions.width, 64)}
step={64} step={64}
isDisabled={!shouldShowBoundingBox}
width={'5rem'} width={'5rem'}
/> />
<IAIIconButton <IAIIconButton
@ -138,10 +132,7 @@ const BoundingBoxSettings = () => {
onClick={handleResetWidth} onClick={handleResetWidth}
icon={<BiReset />} icon={<BiReset />}
styleClass="inpainting-bounding-box-reset-icon-btn" styleClass="inpainting-bounding-box-reset-icon-btn"
isDisabled={ isDisabled={canvasDimensions.width === boundingBoxDimensions.width}
!shouldShowBoundingBox ||
canvasDimensions.width === boundingBoxDimensions.width
}
/> />
</div> </div>
<div className="inpainting-bounding-box-dimensions-slider-numberinput"> <div className="inpainting-bounding-box-dimensions-slider-numberinput">
@ -152,7 +143,6 @@ const BoundingBoxSettings = () => {
step={64} step={64}
value={boundingBoxDimensions.height} value={boundingBoxDimensions.height}
onChange={handleChangeBoundingBoxHeight} onChange={handleChangeBoundingBoxHeight}
isDisabled={!shouldShowBoundingBox}
width={'5rem'} width={'5rem'}
/> />
<IAINumberInput <IAINumberInput
@ -162,7 +152,6 @@ const BoundingBoxSettings = () => {
max={roundDownToMultiple(canvasDimensions.height, 64)} max={roundDownToMultiple(canvasDimensions.height, 64)}
step={64} step={64}
padding="0" padding="0"
isDisabled={!shouldShowBoundingBox}
width={'5rem'} width={'5rem'}
/> />
<IAIIconButton <IAIIconButton
@ -173,7 +162,6 @@ const BoundingBoxSettings = () => {
icon={<BiReset />} icon={<BiReset />}
styleClass="inpainting-bounding-box-reset-icon-btn" styleClass="inpainting-bounding-box-reset-icon-btn"
isDisabled={ isDisabled={
!shouldShowBoundingBox ||
canvasDimensions.height === boundingBoxDimensions.height canvasDimensions.height === boundingBoxDimensions.height
} }
/> />
@ -184,14 +172,12 @@ const BoundingBoxSettings = () => {
isChecked={shouldShowBoundingBoxFill} isChecked={shouldShowBoundingBoxFill}
onChange={handleChangeShouldShowBoundingBoxFill} onChange={handleChangeShouldShowBoundingBoxFill}
styleClass="inpainting-bounding-box-darken" styleClass="inpainting-bounding-box-darken"
isDisabled={!shouldShowBoundingBox}
/> />
<IAICheckbox <IAICheckbox
label="Lock Bounding Box" label="Lock Bounding Box"
isChecked={shouldLockBoundingBox} isChecked={shouldLockBoundingBox}
onChange={handleChangeShouldLockBoundingBox} onChange={handleChangeShouldLockBoundingBox}
styleClass="inpainting-bounding-box-darken" styleClass="inpainting-bounding-box-darken"
isDisabled={!shouldShowBoundingBox}
/> />
</Flex> </Flex>
</div> </div>

View File

@ -56,7 +56,6 @@ const InpaintingCanvas = () => {
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
isDrawing, isDrawing,
shouldLockBoundingBox, shouldLockBoundingBox,
shouldShowBoundingBox,
boundingBoxDimensions, boundingBoxDimensions,
} = useAppSelector(inpaintingCanvasSelector); } = useAppSelector(inpaintingCanvasSelector);
@ -301,10 +300,10 @@ const InpaintingCanvas = () => {
)} )}
</Layer> </Layer>
<Layer> <Layer>
{shouldShowBoundingBox && shouldShowBoundingBoxFill && ( {shouldShowBoundingBoxFill && (
<InpaintingBoundingBoxPreviewOverlay /> <InpaintingBoundingBoxPreviewOverlay />
)} )}
{shouldShowBoundingBox && <InpaintingBoundingBoxPreview />} <InpaintingBoundingBoxPreview />
{shouldLockBoundingBox && ( {shouldLockBoundingBox && (
<InpaintingCanvasBrushPreviewOutline /> <InpaintingCanvasBrushPreviewOutline />
)} )}

View File

@ -51,7 +51,6 @@ const InpaintingControls = () => {
isMaskEmpty, isMaskEmpty,
activeTabName, activeTabName,
showDualDisplay, showDualDisplay,
shouldShowBoundingBox
} = useAppSelector(inpaintingControlsSelector); } = useAppSelector(inpaintingControlsSelector);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@ -161,9 +160,9 @@ const InpaintingControls = () => {
dispatch(toggleShouldLockBoundingBox()); dispatch(toggleShouldLockBoundingBox());
}, },
{ {
enabled: activeTabName === 'inpainting' && shouldShowMask && shouldShowBoundingBox, enabled: activeTabName === 'inpainting' && shouldShowMask,
}, },
[activeTabName, shouldShowMask, shouldShowBoundingBox] [activeTabName, shouldShowMask]
); );
// Undo // Undo

View File

@ -37,7 +37,6 @@ export interface InpaintingState {
boundingBoxDimensions: Dimensions; boundingBoxDimensions: Dimensions;
boundingBoxCoordinate: Vector2d; boundingBoxCoordinate: Vector2d;
boundingBoxPreviewFill: RgbaColor; boundingBoxPreviewFill: RgbaColor;
shouldShowBoundingBox: boolean;
shouldShowBoundingBoxFill: boolean; shouldShowBoundingBoxFill: boolean;
lines: MaskLine[]; lines: MaskLine[];
pastLines: MaskLine[][]; pastLines: MaskLine[][];
@ -64,7 +63,6 @@ const initialInpaintingState: InpaintingState = {
boundingBoxDimensions: { width: 64, height: 64 }, boundingBoxDimensions: { width: 64, height: 64 },
boundingBoxCoordinate: { x: 0, y: 0 }, boundingBoxCoordinate: { x: 0, y: 0 },
boundingBoxPreviewFill: { r: 0, g: 0, b: 0, a: 0.7 }, boundingBoxPreviewFill: { r: 0, g: 0, b: 0, a: 0.7 },
shouldShowBoundingBox: false,
shouldShowBoundingBoxFill: false, shouldShowBoundingBoxFill: false,
cursorPosition: null, cursorPosition: null,
lines: [], lines: [],
@ -304,9 +302,6 @@ export const inpaintingSlice = createSlice({
setIsDrawing: (state, action: PayloadAction<boolean>) => { setIsDrawing: (state, action: PayloadAction<boolean>) => {
state.isDrawing = action.payload; state.isDrawing = action.payload;
}, },
setShouldShowBoundingBox: (state, action: PayloadAction<boolean>) => {
state.shouldShowBoundingBox = action.payload;
},
setClearBrushHistory: (state) => { setClearBrushHistory: (state) => {
state.pastLines = []; state.pastLines = [];
state.futureLines = []; state.futureLines = [];
@ -352,7 +347,6 @@ export const {
setShouldShowBoundingBoxFill, setShouldShowBoundingBoxFill,
setIsDrawing, setIsDrawing,
setShouldShowBrush, setShouldShowBrush,
setShouldShowBoundingBox,
setClearBrushHistory, setClearBrushHistory,
setShouldUseInpaintReplace, setShouldUseInpaintReplace,
setInpaintReplace, setInpaintReplace,

View File

@ -3,7 +3,6 @@ import _ from 'lodash';
import { RootState } from '../../../app/store'; import { RootState } from '../../../app/store';
import { activeTabNameSelector } from '../../options/optionsSelectors'; import { activeTabNameSelector } from '../../options/optionsSelectors';
import { OptionsState } from '../../options/optionsSlice'; import { OptionsState } from '../../options/optionsSlice';
import { tabMap } from '../InvokeTabs';
import { InpaintingState } from './inpaintingSlice'; import { InpaintingState } from './inpaintingSlice';
import { rgbaColorToRgbString } from './util/colorToString'; import { rgbaColorToRgbString } from './util/colorToString';
@ -36,7 +35,6 @@ export const inpaintingControlsSelector = createSelector(
pastLines, pastLines,
futureLines, futureLines,
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
shouldShowBoundingBox,
} = inpainting; } = inpainting;
const { showDualDisplay } = options; const { showDualDisplay } = options;
@ -54,7 +52,6 @@ export const inpaintingControlsSelector = createSelector(
activeTabName, activeTabName,
showDualDisplay, showDualDisplay,
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
shouldShowBoundingBox,
}; };
}, },
{ {
@ -79,7 +76,6 @@ export const inpaintingCanvasSelector = createSelector(
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
isDrawing, isDrawing,
shouldLockBoundingBox, shouldLockBoundingBox,
shouldShowBoundingBox,
boundingBoxDimensions, boundingBoxDimensions,
} = inpainting; } = inpainting;
return { return {
@ -94,7 +90,6 @@ export const inpaintingCanvasSelector = createSelector(
shouldShowBoundingBoxFill, shouldShowBoundingBoxFill,
isDrawing, isDrawing,
shouldLockBoundingBox, shouldLockBoundingBox,
shouldShowBoundingBox,
boundingBoxDimensions, boundingBoxDimensions,
}; };
}, },

View File

@ -1,5 +1,4 @@
import Konva from 'konva'; import Konva from 'konva';
import { IRect } from 'konva/lib/types';
import { MaskLine } from '../inpaintingSlice'; import { MaskLine } from '../inpaintingSlice';
/** /**
@ -12,11 +11,7 @@ import { MaskLine } from '../inpaintingSlice';
* drawing the mask and compositing everything correctly to output a valid * drawing the mask and compositing everything correctly to output a valid
* mask image. * mask image.
*/ */
const generateMask = ( const generateMask = (image: HTMLImageElement, lines: MaskLine[]) => {
image: HTMLImageElement,
lines: MaskLine[],
boundingBox: IRect
) => {
const { width, height } = image; const { width, height } = image;
const offscreenContainer = document.createElement('div'); const offscreenContainer = document.createElement('div');