mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): fix canvas img2img if no init image selected
This commit is contained in:
parent
f488b1a7f2
commit
8ef49c2640
@ -1,26 +1,20 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import { validateSeedWeights } from 'common/util/seedWeightPairs';
|
||||
import { initialCanvasImageSelector } from 'features/canvas/store/canvasSelectors';
|
||||
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import { isEqual } from 'lodash-es';
|
||||
|
||||
export const readinessSelector = createSelector(
|
||||
[
|
||||
generationSelector,
|
||||
systemSelector,
|
||||
initialCanvasImageSelector,
|
||||
activeTabNameSelector,
|
||||
],
|
||||
(generation, system) => {
|
||||
[generationSelector, systemSelector, activeTabNameSelector],
|
||||
(generation, system, activeTabName) => {
|
||||
const {
|
||||
prompt,
|
||||
shouldGenerateVariations,
|
||||
seedWeights,
|
||||
initialImage,
|
||||
seed,
|
||||
isImageToImageEnabled,
|
||||
} = generation;
|
||||
|
||||
const { isProcessing, isConnected } = system;
|
||||
@ -34,7 +28,7 @@ export const readinessSelector = createSelector(
|
||||
reasonsWhyNotReady.push('Missing prompt');
|
||||
}
|
||||
|
||||
if (isImageToImageEnabled && !initialImage) {
|
||||
if (activeTabName === 'img2img' && !initialImage) {
|
||||
isReady = false;
|
||||
reasonsWhyNotReady.push('No initial image selected');
|
||||
}
|
||||
@ -64,10 +58,5 @@ export const readinessSelector = createSelector(
|
||||
// All good
|
||||
return { isReady, reasonsWhyNotReady };
|
||||
},
|
||||
{
|
||||
memoizeOptions: {
|
||||
equalityCheck: isEqual,
|
||||
resultEqualityCheck: isEqual,
|
||||
},
|
||||
}
|
||||
defaultSelectorOptions
|
||||
);
|
||||
|
@ -79,8 +79,6 @@ export const buildCanvasGraphAndBlobs = async (
|
||||
moduleLog.debug(
|
||||
{
|
||||
data: {
|
||||
// baseDataURL,
|
||||
// maskDataURL,
|
||||
baseIsPartiallyTransparent,
|
||||
baseIsFullyTransparent,
|
||||
doesMaskHaveBlackPixels,
|
||||
|
@ -5,8 +5,8 @@ import {
|
||||
ImageToImageInvocation,
|
||||
TextToImageInvocation,
|
||||
} from 'services/api';
|
||||
import { initialImageSelector } from 'features/parameters/store/generationSelectors';
|
||||
import { O } from 'ts-toolbelt';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
|
||||
export const buildImg2ImgNode = (
|
||||
state: RootState,
|
||||
@ -15,6 +15,8 @@ export const buildImg2ImgNode = (
|
||||
const nodeId = uuidv4();
|
||||
const { generation } = state;
|
||||
|
||||
const activeTabName = activeTabNameSelector(state);
|
||||
|
||||
const {
|
||||
prompt,
|
||||
negativePrompt,
|
||||
@ -33,11 +35,6 @@ export const buildImg2ImgNode = (
|
||||
|
||||
// const initialImage = initialImageSelector(state);
|
||||
|
||||
if (!initialImage) {
|
||||
// TODO: handle this
|
||||
throw 'no initial image';
|
||||
}
|
||||
|
||||
const imageToImageNode: ImageToImageInvocation = {
|
||||
id: nodeId,
|
||||
type: 'img2img',
|
||||
@ -48,14 +45,23 @@ export const buildImg2ImgNode = (
|
||||
cfg_scale: cfgScale,
|
||||
scheduler: sampler as ImageToImageInvocation['scheduler'],
|
||||
model,
|
||||
image: {
|
||||
image_name: initialImage.name,
|
||||
image_type: initialImage.type,
|
||||
},
|
||||
strength,
|
||||
fit,
|
||||
};
|
||||
|
||||
// on Canvas tab, we do not manually specific init image
|
||||
if (activeTabName === 'img2img') {
|
||||
if (!initialImage) {
|
||||
// TODO: handle this more better
|
||||
throw 'no initial image';
|
||||
}
|
||||
|
||||
imageToImageNode.image = {
|
||||
image_name: initialImage.name,
|
||||
image_type: initialImage.type,
|
||||
};
|
||||
}
|
||||
|
||||
if (!shouldRandomizeSeed) {
|
||||
imageToImageNode.seed = seed;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||
import { setImg2imgStrength } from 'features/parameters/store/generationSlice';
|
||||
@ -13,32 +14,25 @@ const selector = createSelector(
|
||||
(generation, hotkeys, config) => {
|
||||
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
|
||||
config.sd.img2imgStrength;
|
||||
const { img2imgStrength, isImageToImageEnabled } = generation;
|
||||
const { img2imgStrength } = generation;
|
||||
|
||||
const step = hotkeys.shift ? fineStep : coarseStep;
|
||||
|
||||
return {
|
||||
img2imgStrength,
|
||||
isImageToImageEnabled,
|
||||
initial,
|
||||
min,
|
||||
sliderMax,
|
||||
inputMax,
|
||||
step,
|
||||
};
|
||||
}
|
||||
},
|
||||
defaultSelectorOptions
|
||||
);
|
||||
|
||||
const ImageToImageStrength = () => {
|
||||
const {
|
||||
img2imgStrength,
|
||||
isImageToImageEnabled,
|
||||
initial,
|
||||
min,
|
||||
sliderMax,
|
||||
inputMax,
|
||||
step,
|
||||
} = useAppSelector(selector);
|
||||
const { img2imgStrength, initial, min, sliderMax, inputMax, step } =
|
||||
useAppSelector(selector);
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -64,7 +58,6 @@ const ImageToImageStrength = () => {
|
||||
withInput
|
||||
withSliderMarks
|
||||
withReset
|
||||
isDisabled={!isImageToImageEnabled}
|
||||
sliderNumberInputProps={{ max: inputMax }}
|
||||
/>
|
||||
);
|
||||
|
@ -1,49 +0,0 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import IAISwitch from 'common/components/IAISwitch';
|
||||
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||
import { uiSelector } from 'features/ui/store/uiSelectors';
|
||||
import { shouldShowImageParametersChanged } from 'features/ui/store/uiSlice';
|
||||
import { ChangeEvent } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const selector = createSelector(
|
||||
[uiSelector, generationSelector],
|
||||
(ui, generation) => {
|
||||
const { isImageToImageEnabled } = generation;
|
||||
const { shouldShowImageParameters } = ui;
|
||||
return {
|
||||
isImageToImageEnabled,
|
||||
shouldShowImageParameters,
|
||||
};
|
||||
},
|
||||
defaultSelectorOptions
|
||||
);
|
||||
|
||||
export default function ImageToImageToggle() {
|
||||
const { shouldShowImageParameters } = useAppSelector(selector);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const handleChange = (e: ChangeEvent<HTMLInputElement>) =>
|
||||
dispatch(shouldShowImageParametersChanged(e.target.checked));
|
||||
|
||||
return (
|
||||
<Flex py={1.5} px={4} borderRadius={4}>
|
||||
<IAISwitch
|
||||
label={t('parameters.initialImage')}
|
||||
isChecked={shouldShowImageParameters}
|
||||
width="full"
|
||||
onChange={handleChange}
|
||||
justifyContent="space-between"
|
||||
formLabelProps={{
|
||||
fontWeight: 400,
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
}
|
@ -5,28 +5,27 @@ import SelectImagePlaceholder from 'common/components/SelectImagePlaceholder';
|
||||
import { useGetUrl } from 'common/util/getUrl';
|
||||
import { clearInitialImage } from 'features/parameters/store/generationSlice';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { DragEvent, useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ImageType } from 'services/api';
|
||||
import ImageToImageOverlay from 'common/components/ImageToImageOverlay';
|
||||
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||
import { initialImageSelected } from 'features/parameters/store/actions';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
|
||||
const selector = createSelector(
|
||||
[generationSelector],
|
||||
(generation) => {
|
||||
const { initialImage, isImageToImageEnabled } = generation;
|
||||
const { initialImage } = generation;
|
||||
return {
|
||||
initialImage,
|
||||
isImageToImageEnabled,
|
||||
};
|
||||
},
|
||||
{ memoizeOptions: { resultEqualityCheck: isEqual } }
|
||||
defaultSelectorOptions
|
||||
);
|
||||
|
||||
const InitialImagePreview = () => {
|
||||
const { initialImage, isImageToImageEnabled } = useAppSelector(selector);
|
||||
const { initialImage } = useAppSelector(selector);
|
||||
const { getUrl } = useGetUrl();
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
@ -73,8 +72,6 @@ const InitialImagePreview = () => {
|
||||
sx={{
|
||||
height: 'full',
|
||||
width: 'full',
|
||||
opacity: isImageToImageEnabled ? 1 : 0.5,
|
||||
filter: isImageToImageEnabled ? 'none' : 'auto',
|
||||
blur: '5px',
|
||||
position: 'relative',
|
||||
alignItems: 'center',
|
||||
@ -107,26 +104,6 @@ const InitialImagePreview = () => {
|
||||
)}
|
||||
{!initialImage?.url && <SelectImagePlaceholder />}
|
||||
</Flex>
|
||||
{/* {!isImageToImageEnabled && (
|
||||
<Flex
|
||||
sx={{
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
position: 'absolute',
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
fontWeight={500}
|
||||
fontSize="md"
|
||||
userSelect="none"
|
||||
color="base.200"
|
||||
>
|
||||
Image to Image is Disabled
|
||||
</Text>
|
||||
</Flex>
|
||||
)} */}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@ -35,7 +35,6 @@ export interface GenerationState {
|
||||
shouldUseSymmetry: boolean;
|
||||
horizontalSymmetrySteps: number;
|
||||
verticalSymmetrySteps: number;
|
||||
isImageToImageEnabled: boolean;
|
||||
model: string;
|
||||
shouldUseSeamless: boolean;
|
||||
seamlessXAxis: boolean;
|
||||
@ -71,7 +70,6 @@ export const initialGenerationState: GenerationState = {
|
||||
shouldUseSymmetry: false,
|
||||
horizontalSymmetrySteps: 0,
|
||||
verticalSymmetrySteps: 0,
|
||||
isImageToImageEnabled: false,
|
||||
model: '',
|
||||
shouldUseSeamless: false,
|
||||
seamlessXAxis: true,
|
||||
@ -233,10 +231,6 @@ export const generationSlice = createSlice({
|
||||
},
|
||||
initialImageChanged: (state, action: PayloadAction<InvokeAI.Image>) => {
|
||||
state.initialImage = action.payload;
|
||||
state.isImageToImageEnabled = true;
|
||||
},
|
||||
isImageToImageEnabledChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.isImageToImageEnabled = action.payload;
|
||||
},
|
||||
modelSelected: (state, action: PayloadAction<string>) => {
|
||||
state.model = action.payload;
|
||||
@ -249,9 +243,6 @@ export const {
|
||||
clearInitialImage,
|
||||
resetParametersState,
|
||||
resetSeed,
|
||||
setAllImageToImageParameters,
|
||||
setAllParameters,
|
||||
setAllTextToImageParameters,
|
||||
setCfgScale,
|
||||
setHeight,
|
||||
setImg2imgStrength,
|
||||
@ -282,7 +273,6 @@ export const {
|
||||
setHorizontalSymmetrySteps,
|
||||
setVerticalSymmetrySteps,
|
||||
initialImageChanged,
|
||||
isImageToImageEnabledChanged,
|
||||
modelSelected,
|
||||
setShouldUseNoiseSettings,
|
||||
setSeamless,
|
||||
|
Loading…
Reference in New Issue
Block a user