diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json
index b210ff6b4f..9951b21cd8 100644
--- a/invokeai/frontend/web/public/locales/en.json
+++ b/invokeai/frontend/web/public/locales/en.json
@@ -1111,6 +1111,7 @@
"upscaling": "Upscaling",
"unmasked": "Unmasked",
"useAll": "Use All",
+ "useSize": "Use Size",
"useCpuNoise": "Use CPU Noise",
"cpuNoise": "CPU Noise",
"gpuNoise": "GPU Noise",
diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx
index 10f1be9153..c371e2aee5 100644
--- a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageButtons.tsx
@@ -35,6 +35,7 @@ import {
FaCode,
FaHourglassHalf,
FaQuoteRight,
+ FaRulerVertical,
FaSeedling,
} from 'react-icons/fa';
import { FaCircleNodes, FaEllipsis } from 'react-icons/fa6';
@@ -95,8 +96,12 @@ const CurrentImageButtons = () => {
const toaster = useAppToaster();
const { t } = useTranslation();
- const { recallBothPrompts, recallSeed, recallAllParameters } =
- useRecallParameters();
+ const {
+ recallBothPrompts,
+ recallSeed,
+ recallWidthAndHeight,
+ recallAllParameters,
+ } = useRecallParameters();
const { currentData: imageDTO } = useGetImageDTOQuery(
lastSelectedImage?.image_name ?? skipToken
@@ -117,6 +122,8 @@ const CurrentImageButtons = () => {
dispatch(workflowLoadRequested(workflow));
}, [dispatch, workflow]);
+ useHotkeys('w', handleLoadWorkflow, [workflow]);
+
const handleClickUseAllParameters = useCallback(() => {
recallAllParameters(metadata);
}, [metadata, recallAllParameters]);
@@ -146,7 +153,11 @@ const CurrentImageButtons = () => {
useHotkeys('p', handleUsePrompt, [metadata]);
- useHotkeys('w', handleLoadWorkflow, [workflow]);
+ const handleUseSize = useCallback(() => {
+ recallWidthAndHeight(metadata?.width, metadata?.height);
+ }, [metadata?.width, metadata?.height, recallWidthAndHeight]);
+
+ useHotkeys('d', handleUseSize, [metadata]);
const handleSendToImageToImage = useCallback(() => {
dispatch(sentImageToImg2Img());
@@ -267,6 +278,19 @@ const CurrentImageButtons = () => {
isDisabled={metadata?.seed === null || metadata?.seed === undefined}
onClick={handleUseSeed}
/>
+ }
+ tooltip={`${t('parameters.useSize')} (D)`}
+ aria-label={`${t('parameters.useSize')} (D)`}
+ isDisabled={
+ metadata?.height === null ||
+ metadata?.height === undefined ||
+ metadata?.width === null ||
+ metadata?.width === undefined
+ }
+ onClick={handleUseSize}
+ />
}
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImageDisplay.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImageDisplay.tsx
index 56054e3505..17eeccf306 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImageDisplay.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/InitialImageDisplay.tsx
@@ -5,12 +5,14 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAIIconButton from 'common/components/IAIIconButton';
import { useImageUploadButton } from 'common/hooks/useImageUploadButton';
+import { useRecallParameters } from 'features/parameters/hooks/useRecallParameters';
import { clearInitialImage } from 'features/parameters/store/generationSlice';
import { memo, useCallback } from 'react';
-import { FaUndo, FaUpload } from 'react-icons/fa';
-import InitialImage from './InitialImage';
-import { PostUploadAction } from 'services/api/types';
+import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next';
+import { FaRulerVertical, FaUndo, FaUpload } from 'react-icons/fa';
+import { PostUploadAction } from 'services/api/types';
+import InitialImage from './InitialImage';
const selector = createSelector(
[stateSelector],
@@ -18,6 +20,7 @@ const selector = createSelector(
const { initialImage } = state.generation;
return {
isResetButtonDisabled: !initialImage,
+ initialImage,
};
},
defaultSelectorOptions
@@ -28,7 +31,9 @@ const postUploadAction: PostUploadAction = {
};
const InitialImageDisplay = () => {
- const { isResetButtonDisabled } = useAppSelector(selector);
+ const { recallWidthAndHeight } = useRecallParameters();
+ const { t } = useTranslation();
+ const { isResetButtonDisabled, initialImage } = useAppSelector(selector);
const dispatch = useAppDispatch();
const { getUploadButtonProps, getUploadInputProps } = useImageUploadButton({
@@ -39,7 +44,13 @@ const InitialImageDisplay = () => {
dispatch(clearInitialImage());
}, [dispatch]);
- const { t } = useTranslation();
+ const handleUseSizeInitialImage = useCallback(() => {
+ if (initialImage) {
+ recallWidthAndHeight(initialImage.width, initialImage.height);
+ }
+ }, [initialImage, recallWidthAndHeight]);
+
+ useHotkeys('shift+d', handleUseSizeInitialImage, [initialImage]);
return (
{
icon={}
{...getUploadButtonProps()}
/>
+ }
+ onClick={handleUseSizeInitialImage}
+ isDisabled={isResetButtonDisabled}
+ />
{
[dispatch, parameterSetToast, parameterNotSetToast]
);
+ /**
+ * Recall width and height with toast
+ */
+ const recallWidthAndHeight = useCallback(
+ (width: unknown, height: unknown) => {
+ if (!isValidWidth(width)) {
+ allParameterNotSetToast();
+ return;
+ }
+ if (!isValidHeight(height)) {
+ allParameterNotSetToast();
+ return;
+ }
+ dispatch(setHeight(height));
+ dispatch(setWidth(width));
+ allParameterSetToast();
+ },
+ [dispatch, allParameterSetToast, allParameterNotSetToast]
+ );
+
/**
* Recall strength with toast
*/
@@ -966,6 +986,7 @@ export const useRecallParameters = () => {
recallSteps,
recallWidth,
recallHeight,
+ recallWidthAndHeight,
recallStrength,
recallHrfEnabled,
recallHrfStrength,