mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): clamp incoming w/h to ensure always a multiple of 8
When recalling metadata and/or using control image dimensions, it was possible to set a width or height that was not a multiple of 8, resulting in generation failures. Added a `clamp` option to the w/h actions to fix this. The option is used for all untrusted sources - everything except for the w/h number inputs, which clamp the values themselves.
This commit is contained in:
parent
1b13fee256
commit
474eab6f8a
@ -96,16 +96,16 @@ export const addSetDefaultSettingsListener = (startAppListening: AppStartListeni
|
||||
dispatch(setScheduler(scheduler));
|
||||
}
|
||||
}
|
||||
|
||||
const setSizeOptions = { updateAspectRatio: true, clamp: true };
|
||||
if (width) {
|
||||
if (isParameterWidth(width)) {
|
||||
dispatch(widthChanged({ width, updateAspectRatio: true }));
|
||||
dispatch(widthChanged({ width, ...setSizeOptions }));
|
||||
}
|
||||
}
|
||||
|
||||
if (height) {
|
||||
if (isParameterHeight(height)) {
|
||||
dispatch(heightChanged({ height, updateAspectRatio: true }));
|
||||
dispatch(heightChanged({ height, ...setSizeOptions }));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,12 +96,13 @@ const ControlAdapterImagePreview = ({ isSmall, id }: Props) => {
|
||||
if (activeTabName === 'unifiedCanvas') {
|
||||
dispatch(setBoundingBoxDimensions({ width: controlImage.width, height: controlImage.height }, optimalDimension));
|
||||
} else {
|
||||
const options = { updateAspectRatio: true, clamp: true };
|
||||
const { width, height } = calculateNewSize(
|
||||
controlImage.width / controlImage.height,
|
||||
optimalDimension * optimalDimension
|
||||
);
|
||||
dispatch(widthChanged({ width, updateAspectRatio: true }));
|
||||
dispatch(heightChanged({ height, updateAspectRatio: true }));
|
||||
dispatch(widthChanged({ width, ...options }));
|
||||
dispatch(heightChanged({ height, ...options }));
|
||||
}
|
||||
}, [controlImage, activeTabName, dispatch, optimalDimension]);
|
||||
|
||||
|
@ -85,17 +85,19 @@ export const ControlAdapterImagePreview = memo(
|
||||
setBoundingBoxDimensions({ width: controlImage.width, height: controlImage.height }, optimalDimension)
|
||||
);
|
||||
} else {
|
||||
const options = { updateAspectRatio: true, clamp: true };
|
||||
|
||||
if (shift) {
|
||||
const { width, height } = controlImage;
|
||||
dispatch(widthChanged({ width, updateAspectRatio: true }));
|
||||
dispatch(heightChanged({ height, updateAspectRatio: true }));
|
||||
dispatch(widthChanged({ width, ...options }));
|
||||
dispatch(heightChanged({ height, ...options }));
|
||||
} else {
|
||||
const { width, height } = calculateNewSize(
|
||||
controlImage.width / controlImage.height,
|
||||
optimalDimension * optimalDimension
|
||||
);
|
||||
dispatch(widthChanged({ width, updateAspectRatio: true }));
|
||||
dispatch(heightChanged({ height, updateAspectRatio: true }));
|
||||
dispatch(widthChanged({ width, ...options }));
|
||||
dispatch(heightChanged({ height, ...options }));
|
||||
}
|
||||
}
|
||||
}, [controlImage, activeTabName, dispatch, optimalDimension, shift]);
|
||||
|
@ -51,17 +51,18 @@ export const IPAdapterImagePreview = memo(
|
||||
setBoundingBoxDimensions({ width: controlImage.width, height: controlImage.height }, optimalDimension)
|
||||
);
|
||||
} else {
|
||||
const options = { updateAspectRatio: true, clamp: true };
|
||||
if (shift) {
|
||||
const { width, height } = controlImage;
|
||||
dispatch(widthChanged({ width, updateAspectRatio: true }));
|
||||
dispatch(heightChanged({ height, updateAspectRatio: true }));
|
||||
dispatch(widthChanged({ width, ...options }));
|
||||
dispatch(heightChanged({ height, ...options }));
|
||||
} else {
|
||||
const { width, height } = calculateNewSize(
|
||||
controlImage.width / controlImage.height,
|
||||
optimalDimension * optimalDimension
|
||||
);
|
||||
dispatch(widthChanged({ width, updateAspectRatio: true }));
|
||||
dispatch(heightChanged({ height, updateAspectRatio: true }));
|
||||
dispatch(widthChanged({ width, ...options }));
|
||||
dispatch(heightChanged({ height, ...options }));
|
||||
}
|
||||
}
|
||||
}, [controlImage, activeTabName, dispatch, optimalDimension, shift]);
|
||||
|
@ -3,6 +3,7 @@ import { createSlice, isAnyOf } from '@reduxjs/toolkit';
|
||||
import type { PersistConfig, RootState } from 'app/store/store';
|
||||
import { moveBackward, moveForward, moveToBack, moveToFront } from 'common/util/arrayUtils';
|
||||
import { deepClone } from 'common/util/deepClone';
|
||||
import { roundDownToMultiple } from 'common/util/roundDownToMultiple';
|
||||
import type {
|
||||
CLIPVisionModelV2,
|
||||
ControlModeV2,
|
||||
@ -626,20 +627,20 @@ export const controlLayersSlice = createSlice({
|
||||
shouldConcatPromptsChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldConcatPrompts = action.payload;
|
||||
},
|
||||
widthChanged: (state, action: PayloadAction<{ width: number; updateAspectRatio?: boolean }>) => {
|
||||
const { width, updateAspectRatio } = action.payload;
|
||||
state.size.width = width;
|
||||
widthChanged: (state, action: PayloadAction<{ width: number; updateAspectRatio?: boolean; clamp?: boolean }>) => {
|
||||
const { width, updateAspectRatio, clamp } = action.payload;
|
||||
state.size.width = clamp ? Math.max(roundDownToMultiple(width, 8), 64) : width;
|
||||
if (updateAspectRatio) {
|
||||
state.size.aspectRatio.value = width / state.size.height;
|
||||
state.size.aspectRatio.value = state.size.width / state.size.height;
|
||||
state.size.aspectRatio.id = 'Free';
|
||||
state.size.aspectRatio.isLocked = false;
|
||||
}
|
||||
},
|
||||
heightChanged: (state, action: PayloadAction<{ height: number; updateAspectRatio?: boolean }>) => {
|
||||
const { height, updateAspectRatio } = action.payload;
|
||||
state.size.height = height;
|
||||
heightChanged: (state, action: PayloadAction<{ height: number; updateAspectRatio?: boolean; clamp?: boolean }>) => {
|
||||
const { height, updateAspectRatio, clamp } = action.payload;
|
||||
state.size.height = clamp ? Math.max(roundDownToMultiple(height, 8), 64) : height;
|
||||
if (updateAspectRatio) {
|
||||
state.size.aspectRatio.value = state.size.width / height;
|
||||
state.size.aspectRatio.value = state.size.width / state.size.height;
|
||||
state.size.aspectRatio.id = 'Free';
|
||||
state.size.aspectRatio.isLocked = false;
|
||||
}
|
||||
|
@ -110,12 +110,14 @@ const recallInitialImage: MetadataRecallFunc<ImageDTO> = async (imageDTO) => {
|
||||
getStore().dispatch(initialImageChanged(imageDTO));
|
||||
};
|
||||
|
||||
const setSizeOptions = { updateAspectRatio: true, clamp: true };
|
||||
|
||||
const recallWidth: MetadataRecallFunc<ParameterWidth> = (width) => {
|
||||
getStore().dispatch(widthChanged({ width, updateAspectRatio: true }));
|
||||
getStore().dispatch(widthChanged({ width, ...setSizeOptions }));
|
||||
};
|
||||
|
||||
const recallHeight: MetadataRecallFunc<ParameterHeight> = (height) => {
|
||||
getStore().dispatch(heightChanged({ height, updateAspectRatio: true }));
|
||||
getStore().dispatch(heightChanged({ height, ...setSizeOptions }));
|
||||
};
|
||||
|
||||
const recallSteps: MetadataRecallFunc<ParameterSteps> = (steps) => {
|
||||
|
Loading…
Reference in New Issue
Block a user