mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' into release/make-web-dist-startable
This commit is contained in:
commit
dd157bce85
@ -56,7 +56,7 @@ class TextToImageInvocation(BaseInvocation, SDImageInvocation):
|
|||||||
width: int = Field(default=512, multiple_of=8, gt=0, description="The width of the resulting image", )
|
width: int = Field(default=512, multiple_of=8, gt=0, description="The width of the resulting image", )
|
||||||
height: int = Field(default=512, multiple_of=8, gt=0, description="The height of the resulting image", )
|
height: int = Field(default=512, multiple_of=8, gt=0, description="The height of the resulting image", )
|
||||||
cfg_scale: float = Field(default=7.5, ge=1, description="The Classifier-Free Guidance, higher values may result in a result closer to the prompt", )
|
cfg_scale: float = Field(default=7.5, ge=1, description="The Classifier-Free Guidance, higher values may result in a result closer to the prompt", )
|
||||||
scheduler: SAMPLER_NAME_VALUES = Field(default="lms", description="The scheduler to use" )
|
scheduler: SAMPLER_NAME_VALUES = Field(default="euler", description="The scheduler to use" )
|
||||||
model: str = Field(default="", description="The model to use (currently ignored)")
|
model: str = Field(default="", description="The model to use (currently ignored)")
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ class TextToLatentsInvocation(BaseInvocation):
|
|||||||
noise: Optional[LatentsField] = Field(description="The noise to use")
|
noise: Optional[LatentsField] = Field(description="The noise to use")
|
||||||
steps: int = Field(default=10, gt=0, description="The number of steps to use to generate the image")
|
steps: int = Field(default=10, gt=0, description="The number of steps to use to generate the image")
|
||||||
cfg_scale: float = Field(default=7.5, gt=0, description="The Classifier-Free Guidance, higher values may result in a result closer to the prompt", )
|
cfg_scale: float = Field(default=7.5, gt=0, description="The Classifier-Free Guidance, higher values may result in a result closer to the prompt", )
|
||||||
scheduler: SAMPLER_NAME_VALUES = Field(default="lms", description="The scheduler to use" )
|
scheduler: SAMPLER_NAME_VALUES = Field(default="euler", description="The scheduler to use" )
|
||||||
model: str = Field(default="", description="The model to use (currently ignored)")
|
model: str = Field(default="", description="The model to use (currently ignored)")
|
||||||
# seamless: bool = Field(default=False, description="Whether or not to generate an image that can tile without seams", )
|
# seamless: bool = Field(default=False, description="Whether or not to generate an image that can tile without seams", )
|
||||||
# seamless_axes: str = Field(default="", description="The axes to tile the image on, 'x' and/or 'y'")
|
# seamless_axes: str = Field(default="", description="The axes to tile the image on, 'x' and/or 'y'")
|
||||||
|
@ -109,8 +109,9 @@ const currentImageButtonsSelector = createSelector(
|
|||||||
isLightboxOpen,
|
isLightboxOpen,
|
||||||
shouldHidePreview,
|
shouldHidePreview,
|
||||||
image: selectedImage,
|
image: selectedImage,
|
||||||
seed: selectedImage?.metadata?.invokeai?.node?.seed,
|
seed: selectedImage?.metadata?.seed,
|
||||||
prompt: selectedImage?.metadata?.invokeai?.node?.prompt,
|
prompt: selectedImage?.metadata?.positive_conditioning,
|
||||||
|
negativePrompt: selectedImage?.metadata?.negative_conditioning,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -245,13 +246,16 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleUseSeed = useCallback(() => {
|
const handleUseSeed = useCallback(() => {
|
||||||
recallSeed(image?.metadata?.invokeai?.node?.seed);
|
recallSeed(image?.metadata?.seed);
|
||||||
}, [image, recallSeed]);
|
}, [image, recallSeed]);
|
||||||
|
|
||||||
useHotkeys('s', handleUseSeed, [image]);
|
useHotkeys('s', handleUseSeed, [image]);
|
||||||
|
|
||||||
const handleUsePrompt = useCallback(() => {
|
const handleUsePrompt = useCallback(() => {
|
||||||
recallPrompt(image?.metadata?.invokeai?.node?.prompt);
|
recallPrompt(
|
||||||
|
image?.metadata?.positive_conditioning,
|
||||||
|
image?.metadata?.negative_conditioning
|
||||||
|
);
|
||||||
}, [image, recallPrompt]);
|
}, [image, recallPrompt]);
|
||||||
|
|
||||||
useHotkeys('p', handleUsePrompt, [image]);
|
useHotkeys('p', handleUsePrompt, [image]);
|
||||||
@ -454,7 +458,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
{t('parameters.copyImageToLink')}
|
{t('parameters.copyImageToLink')}
|
||||||
</IAIButton>
|
</IAIButton>
|
||||||
|
|
||||||
<Link download={true} href={getUrl(image?.url ?? '')}>
|
<Link download={true} href={getUrl(image?.image_url ?? '')}>
|
||||||
<IAIButton leftIcon={<FaDownload />} size="sm" w="100%">
|
<IAIButton leftIcon={<FaDownload />} size="sm" w="100%">
|
||||||
{t('parameters.downloadImage')}
|
{t('parameters.downloadImage')}
|
||||||
</IAIButton>
|
</IAIButton>
|
||||||
@ -500,7 +504,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
icon={<FaQuoteRight />}
|
icon={<FaQuoteRight />}
|
||||||
tooltip={`${t('parameters.usePrompt')} (P)`}
|
tooltip={`${t('parameters.usePrompt')} (P)`}
|
||||||
aria-label={`${t('parameters.usePrompt')} (P)`}
|
aria-label={`${t('parameters.usePrompt')} (P)`}
|
||||||
isDisabled={!image?.metadata?.invokeai?.node?.prompt}
|
isDisabled={!image?.metadata?.positive_conditioning}
|
||||||
onClick={handleUsePrompt}
|
onClick={handleUsePrompt}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -508,7 +512,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
icon={<FaSeedling />}
|
icon={<FaSeedling />}
|
||||||
tooltip={`${t('parameters.useSeed')} (S)`}
|
tooltip={`${t('parameters.useSeed')} (S)`}
|
||||||
aria-label={`${t('parameters.useSeed')} (S)`}
|
aria-label={`${t('parameters.useSeed')} (S)`}
|
||||||
isDisabled={!image?.metadata?.invokeai?.node?.seed}
|
isDisabled={!image?.metadata?.seed}
|
||||||
onClick={handleUseSeed}
|
onClick={handleUseSeed}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -517,9 +521,8 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
tooltip={`${t('parameters.useAll')} (A)`}
|
tooltip={`${t('parameters.useAll')} (A)`}
|
||||||
aria-label={`${t('parameters.useAll')} (A)`}
|
aria-label={`${t('parameters.useAll')} (A)`}
|
||||||
isDisabled={
|
isDisabled={
|
||||||
!['txt2img', 'img2img', 'inpaint'].includes(
|
// not sure what this list should be
|
||||||
String(image?.metadata?.invokeai?.node?.type)
|
!['t2l', 'l2l', 'inpaint'].includes(String(image?.metadata?.type))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
onClick={handleClickUseAllParameters}
|
onClick={handleClickUseAllParameters}
|
||||||
/>
|
/>
|
||||||
|
@ -155,7 +155,10 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
|||||||
|
|
||||||
// Recall parameters handlers
|
// Recall parameters handlers
|
||||||
const handleRecallPrompt = useCallback(() => {
|
const handleRecallPrompt = useCallback(() => {
|
||||||
recallPrompt(image.metadata?.positive_conditioning);
|
recallPrompt(
|
||||||
|
image.metadata?.positive_conditioning,
|
||||||
|
image.metadata?.negative_conditioning
|
||||||
|
);
|
||||||
}, [image, recallPrompt]);
|
}, [image, recallPrompt]);
|
||||||
|
|
||||||
const handleRecallSeed = useCallback(() => {
|
const handleRecallSeed = useCallback(() => {
|
||||||
@ -248,7 +251,8 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
|||||||
icon={<IoArrowUndoCircleOutline />}
|
icon={<IoArrowUndoCircleOutline />}
|
||||||
onClickCapture={handleUseAllParameters}
|
onClickCapture={handleUseAllParameters}
|
||||||
isDisabled={
|
isDisabled={
|
||||||
!['txt2img', 'img2img', 'inpaint'].includes(
|
// what should these be
|
||||||
|
!['t2l', 'l2l', 'inpaint'].includes(
|
||||||
String(image?.metadata?.type)
|
String(image?.metadata?.type)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -8,29 +8,20 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import * as InvokeAI from 'app/types/invokeai';
|
|
||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
import { useGetUrl } from 'common/util/getUrl';
|
import { useGetUrl } from 'common/util/getUrl';
|
||||||
import promptToString from 'common/util/promptToString';
|
import promptToString from 'common/util/promptToString';
|
||||||
import { seedWeightsToString } from 'common/util/seedWeightPairs';
|
|
||||||
import useSetBothPrompts from 'features/parameters/hooks/usePrompt';
|
|
||||||
import {
|
import {
|
||||||
setCfgScale,
|
setCfgScale,
|
||||||
setHeight,
|
setHeight,
|
||||||
setImg2imgStrength,
|
setImg2imgStrength,
|
||||||
setNegativePrompt,
|
setNegativePrompt,
|
||||||
setPerlin,
|
|
||||||
setPositivePrompt,
|
setPositivePrompt,
|
||||||
setScheduler,
|
setScheduler,
|
||||||
setSeamless,
|
|
||||||
setSeed,
|
setSeed,
|
||||||
setSeedWeights,
|
|
||||||
setShouldFitToWidthHeight,
|
|
||||||
setSteps,
|
setSteps,
|
||||||
setThreshold,
|
|
||||||
setWidth,
|
setWidth,
|
||||||
} from 'features/parameters/store/generationSlice';
|
} from 'features/parameters/store/generationSlice';
|
||||||
import { setHiresFix } from 'features/parameters/store/postprocessingSlice';
|
|
||||||
import { setShouldShowImageDetails } from 'features/ui/store/uiSlice';
|
import { setShouldShowImageDetails } from 'features/ui/store/uiSlice';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
@ -39,7 +30,6 @@ import { FaCopy } from 'react-icons/fa';
|
|||||||
import { IoArrowUndoCircleOutline } from 'react-icons/io5';
|
import { IoArrowUndoCircleOutline } from 'react-icons/io5';
|
||||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||||
import { ImageDTO } from 'services/api';
|
import { ImageDTO } from 'services/api';
|
||||||
import { filter } from 'lodash-es';
|
|
||||||
import { Scheduler } from 'app/constants';
|
import { Scheduler } from 'app/constants';
|
||||||
|
|
||||||
type MetadataItemProps = {
|
type MetadataItemProps = {
|
||||||
@ -126,8 +116,6 @@ const memoEqualityCheck = (
|
|||||||
const ImageMetadataViewer = memo(({ image }: ImageMetadataViewerProps) => {
|
const ImageMetadataViewer = memo(({ image }: ImageMetadataViewerProps) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const setBothPrompts = useSetBothPrompts();
|
|
||||||
|
|
||||||
useHotkeys('esc', () => {
|
useHotkeys('esc', () => {
|
||||||
dispatch(setShouldShowImageDetails(false));
|
dispatch(setShouldShowImageDetails(false));
|
||||||
});
|
});
|
||||||
|
@ -33,7 +33,7 @@ export const nextPrevImageButtonsSelector = createSelector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const currentImageIndex = state[currentCategory].ids.findIndex(
|
const currentImageIndex = state[currentCategory].ids.findIndex(
|
||||||
(i) => i === selectedImage.name
|
(i) => i === selectedImage.image_name
|
||||||
);
|
);
|
||||||
|
|
||||||
const nextImageIndex = clamp(
|
const nextImageIndex = clamp(
|
||||||
|
@ -11,7 +11,7 @@ import { addNoiseNodes } from '../nodeBuilders/addNoiseNodes';
|
|||||||
const POSITIVE_CONDITIONING = 'positive_conditioning';
|
const POSITIVE_CONDITIONING = 'positive_conditioning';
|
||||||
const NEGATIVE_CONDITIONING = 'negative_conditioning';
|
const NEGATIVE_CONDITIONING = 'negative_conditioning';
|
||||||
const TEXT_TO_LATENTS = 'text_to_latents';
|
const TEXT_TO_LATENTS = 'text_to_latents';
|
||||||
const LATENTS_TO_IMAGE = 'latnets_to_image';
|
const LATENTS_TO_IMAGE = 'latents_to_image';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the Text to Image tab graph.
|
* Builds the Text to Image tab graph.
|
||||||
|
@ -21,8 +21,8 @@ export const useParameters = () => {
|
|||||||
* Sets prompt with toast
|
* Sets prompt with toast
|
||||||
*/
|
*/
|
||||||
const recallPrompt = useCallback(
|
const recallPrompt = useCallback(
|
||||||
(prompt: unknown) => {
|
(prompt: unknown, negativePrompt?: unknown) => {
|
||||||
if (!isString(prompt)) {
|
if (!isString(prompt) || !isString(negativePrompt)) {
|
||||||
toaster({
|
toaster({
|
||||||
title: t('toast.promptNotSet'),
|
title: t('toast.promptNotSet'),
|
||||||
description: t('toast.promptNotSetDesc'),
|
description: t('toast.promptNotSetDesc'),
|
||||||
@ -33,7 +33,7 @@ export const useParameters = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setBothPrompts(prompt);
|
setBothPrompts(prompt, negativePrompt);
|
||||||
toaster({
|
toaster({
|
||||||
title: t('toast.promptSet'),
|
title: t('toast.promptSet'),
|
||||||
status: 'info',
|
status: 'info',
|
||||||
@ -112,12 +112,13 @@ export const useParameters = () => {
|
|||||||
const recallAllParameters = useCallback(
|
const recallAllParameters = useCallback(
|
||||||
(image: ImageDTO | undefined) => {
|
(image: ImageDTO | undefined) => {
|
||||||
const type = image?.metadata?.type;
|
const type = image?.metadata?.type;
|
||||||
if (['txt2img', 'img2img', 'inpaint'].includes(String(type))) {
|
// not sure what this list should be
|
||||||
|
if (['t2l', 'l2l', 'inpaint'].includes(String(type))) {
|
||||||
dispatch(allParametersSet(image));
|
dispatch(allParametersSet(image));
|
||||||
|
|
||||||
if (image?.metadata?.type === 'img2img') {
|
if (image?.metadata?.type === 'l2l') {
|
||||||
dispatch(setActiveTab('img2img'));
|
dispatch(setActiveTab('img2img'));
|
||||||
} else if (image?.metadata?.type === 'txt2img') {
|
} else if (image?.metadata?.type === 't2l') {
|
||||||
dispatch(setActiveTab('txt2img'));
|
dispatch(setActiveTab('txt2img'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,15 +12,8 @@ const useSetBothPrompts = () => {
|
|||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
return useCallback(
|
return useCallback(
|
||||||
(inputPrompt: InvokeAI.Prompt) => {
|
(inputPrompt: InvokeAI.Prompt, negativePrompt: InvokeAI.Prompt) => {
|
||||||
const promptString =
|
dispatch(setPositivePrompt(inputPrompt));
|
||||||
typeof inputPrompt === 'string'
|
|
||||||
? inputPrompt
|
|
||||||
: promptToString(inputPrompt);
|
|
||||||
|
|
||||||
const [prompt, negativePrompt] = getPromptAndNegative(promptString);
|
|
||||||
|
|
||||||
dispatch(setPositivePrompt(prompt));
|
|
||||||
dispatch(setNegativePrompt(negativePrompt));
|
dispatch(setNegativePrompt(negativePrompt));
|
||||||
},
|
},
|
||||||
[dispatch]
|
[dispatch]
|
||||||
|
@ -52,7 +52,7 @@ export const initialGenerationState: GenerationState = {
|
|||||||
perlin: 0,
|
perlin: 0,
|
||||||
positivePrompt: '',
|
positivePrompt: '',
|
||||||
negativePrompt: '',
|
negativePrompt: '',
|
||||||
scheduler: 'lms',
|
scheduler: 'euler',
|
||||||
seamBlur: 16,
|
seamBlur: 16,
|
||||||
seamSize: 96,
|
seamSize: 96,
|
||||||
seamSteps: 30,
|
seamSteps: 30,
|
||||||
|
@ -7,19 +7,29 @@ export const setAllParametersReducer = (
|
|||||||
state: Draft<GenerationState>,
|
state: Draft<GenerationState>,
|
||||||
action: PayloadAction<ImageDTO | undefined>
|
action: PayloadAction<ImageDTO | undefined>
|
||||||
) => {
|
) => {
|
||||||
const node = action.payload?.metadata.invokeai?.node;
|
const metadata = action.payload?.metadata;
|
||||||
|
|
||||||
if (!node) {
|
if (!metadata) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// not sure what this list should be
|
||||||
if (
|
if (
|
||||||
node.type === 'txt2img' ||
|
metadata.type === 't2l' ||
|
||||||
node.type === 'img2img' ||
|
metadata.type === 'l2l' ||
|
||||||
node.type === 'inpaint'
|
metadata.type === 'inpaint'
|
||||||
) {
|
) {
|
||||||
const { cfg_scale, height, model, prompt, scheduler, seed, steps, width } =
|
const {
|
||||||
node;
|
cfg_scale,
|
||||||
|
height,
|
||||||
|
model,
|
||||||
|
positive_conditioning,
|
||||||
|
negative_conditioning,
|
||||||
|
scheduler,
|
||||||
|
seed,
|
||||||
|
steps,
|
||||||
|
width,
|
||||||
|
} = metadata;
|
||||||
|
|
||||||
if (cfg_scale !== undefined) {
|
if (cfg_scale !== undefined) {
|
||||||
state.cfgScale = Number(cfg_scale);
|
state.cfgScale = Number(cfg_scale);
|
||||||
@ -30,8 +40,11 @@ export const setAllParametersReducer = (
|
|||||||
if (model !== undefined) {
|
if (model !== undefined) {
|
||||||
state.model = String(model);
|
state.model = String(model);
|
||||||
}
|
}
|
||||||
if (prompt !== undefined) {
|
if (positive_conditioning !== undefined) {
|
||||||
state.positivePrompt = String(prompt);
|
state.positivePrompt = String(positive_conditioning);
|
||||||
|
}
|
||||||
|
if (negative_conditioning !== undefined) {
|
||||||
|
state.negativePrompt = String(negative_conditioning);
|
||||||
}
|
}
|
||||||
if (scheduler !== undefined) {
|
if (scheduler !== undefined) {
|
||||||
const schedulerString = String(scheduler);
|
const schedulerString = String(scheduler);
|
||||||
@ -51,8 +64,8 @@ export const setAllParametersReducer = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.type === 'img2img') {
|
if (metadata.type === 'l2l') {
|
||||||
const { fit, image } = node as ImageToImageInvocation;
|
const { fit, image } = metadata as ImageToImageInvocation;
|
||||||
|
|
||||||
if (fit !== undefined) {
|
if (fit !== undefined) {
|
||||||
state.shouldFitToWidthHeight = Boolean(fit);
|
state.shouldFitToWidthHeight = Boolean(fit);
|
||||||
|
Loading…
Reference in New Issue
Block a user