mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
feat(ui): add compositeMaskedRegions setting
This commit is contained in:
@@ -1673,6 +1673,7 @@
|
||||
"clearCaches": "Clear Caches",
|
||||
"recalculateRects": "Recalculate Rects",
|
||||
"clipToBbox": "Clip Strokes to Bbox",
|
||||
"compositeMaskedRegions": "Composite Masked Regions",
|
||||
"addLayer": "Add Layer",
|
||||
"duplicate": "Duplicate",
|
||||
"moveToFront": "Move to Front",
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Checkbox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import {
|
||||
selectCanvasSettingsSlice,
|
||||
settingsCompositeMaskedRegionsChanged,
|
||||
} from 'features/controlLayers/store/canvasSettingsSlice';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const selectCompositeMaskedRegions = createSelector(
|
||||
selectCanvasSettingsSlice,
|
||||
(canvasSettings) => canvasSettings.compositeMaskedRegions
|
||||
);
|
||||
|
||||
export const CanvasSettingsCompositeMaskedRegionsCheckbox = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const compositeMaskedRegions = useAppSelector(selectCompositeMaskedRegions);
|
||||
const onChange = useCallback(
|
||||
(e: ChangeEvent<HTMLInputElement>) => dispatch(settingsCompositeMaskedRegionsChanged(e.target.checked)),
|
||||
[dispatch]
|
||||
);
|
||||
return (
|
||||
<FormControl w="full">
|
||||
<FormLabel flexGrow={1}>{t('controlLayers.compositeMaskedRegions')}</FormLabel>
|
||||
<Checkbox isChecked={compositeMaskedRegions} onChange={onChange} />
|
||||
</FormControl>
|
||||
);
|
||||
});
|
||||
|
||||
CanvasSettingsCompositeMaskedRegionsCheckbox.displayName = 'CanvasSettingsCompositeMaskedRegionsCheckbox';
|
||||
@@ -13,6 +13,7 @@ import { CanvasSettingsAutoSaveCheckbox } from 'features/controlLayers/component
|
||||
import { CanvasSettingsClearCachesButton } from 'features/controlLayers/components/Settings/CanvasSettingsClearCachesButton';
|
||||
import { CanvasSettingsClearHistoryButton } from 'features/controlLayers/components/Settings/CanvasSettingsClearHistoryButton';
|
||||
import { CanvasSettingsClipToBboxCheckbox } from 'features/controlLayers/components/Settings/CanvasSettingsClipToBboxCheckbox';
|
||||
import { CanvasSettingsCompositeMaskedRegionsCheckbox } from 'features/controlLayers/components/Settings/CanvasSettingsCompositeMaskedRegionsCheckbox';
|
||||
import { CanvasSettingsDynamicGridSwitch } from 'features/controlLayers/components/Settings/CanvasSettingsDynamicGridSwitch';
|
||||
import { CanvasSettingsInvertScrollCheckbox } from 'features/controlLayers/components/Settings/CanvasSettingsInvertScrollCheckbox';
|
||||
import { CanvasSettingsLogDebugInfoButton } from 'features/controlLayers/components/Settings/CanvasSettingsLogDebugInfo';
|
||||
@@ -37,6 +38,7 @@ export const CanvasSettingsPopover = memo(() => {
|
||||
<CanvasSettingsAutoSaveCheckbox />
|
||||
<CanvasSettingsInvertScrollCheckbox />
|
||||
<CanvasSettingsClipToBboxCheckbox />
|
||||
<CanvasSettingsCompositeMaskedRegionsCheckbox />
|
||||
<CanvasSettingsDynamicGridSwitch />
|
||||
<CanvasSettingsShowHUDSwitch />
|
||||
<CanvasSettingsResetButton />
|
||||
|
||||
@@ -8,8 +8,9 @@ export type CanvasSettingsState = {
|
||||
*/
|
||||
showHUD: boolean;
|
||||
/**
|
||||
* Whether to automatically save canvas generations to the gallery. If in Save to Gallery mode, this setting will be
|
||||
* ignored, and all generations will be saved.
|
||||
* Whether to automatically save canvas generations to the gallery.
|
||||
*
|
||||
* When `sendToCanvas` is disabled, this setting is ignored, and images are always saved to the gallery.
|
||||
*/
|
||||
autoSave: boolean;
|
||||
/**
|
||||
@@ -42,6 +43,14 @@ export type CanvasSettingsState = {
|
||||
* the gallery.
|
||||
*/
|
||||
sendToCanvas: boolean;
|
||||
/**
|
||||
* Whether to composite inpainted/outpainted regions back onto the source image when saving canvas generations.
|
||||
*
|
||||
* If disabled, inpainted/outpainted regions will be saved with a transparent background.
|
||||
*
|
||||
* When `sendToCanvas` is disabled, this setting is ignored, masked regions will always be composited.
|
||||
*/
|
||||
compositeMaskedRegions: boolean;
|
||||
|
||||
// TODO(psyche): These are copied from old canvas state, need to be implemented
|
||||
// imageSmoothing: boolean;
|
||||
@@ -59,6 +68,7 @@ const initialState: CanvasSettingsState = {
|
||||
invertScrollForToolWidth: false,
|
||||
color: { r: 31, g: 160, b: 224, a: 1 }, // invokeBlue.500
|
||||
sendToCanvas: false,
|
||||
compositeMaskedRegions: false,
|
||||
};
|
||||
|
||||
export const canvasSettingsSlice = createSlice({
|
||||
@@ -92,6 +102,9 @@ export const canvasSettingsSlice = createSlice({
|
||||
settingsSendToCanvasChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.sendToCanvas = action.payload;
|
||||
},
|
||||
settingsCompositeMaskedRegionsChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.compositeMaskedRegions = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -105,6 +118,7 @@ export const {
|
||||
settingsColorChanged,
|
||||
settingsInvertScrollForToolWidthChanged,
|
||||
settingsSendToCanvasChanged,
|
||||
settingsCompositeMaskedRegionsChanged,
|
||||
} = canvasSettingsSlice.actions;
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
|
||||
@@ -29,7 +29,6 @@ export const addInpaint = async (
|
||||
const canvas = selectCanvasSlice(state);
|
||||
|
||||
const { bbox } = canvas;
|
||||
const { sendToCanvas } = canvasSettings;
|
||||
|
||||
const initialImage = await manager.compositor.getCompositeRasterLayerImageDTO(bbox.rect);
|
||||
const maskImage = await manager.compositor.getCompositeInpaintMaskImageDTO(bbox.rect);
|
||||
@@ -99,7 +98,7 @@ export const addInpaint = async (
|
||||
g.addEdge(resizeImageToOriginalSize, 'image', canvasPasteBack, 'generated_image');
|
||||
g.addEdge(resizeMaskToOriginalSize, 'image', canvasPasteBack, 'mask');
|
||||
|
||||
if (!sendToCanvas) {
|
||||
if (!canvasSettings.sendToCanvas || canvasSettings.compositeMaskedRegions) {
|
||||
canvasPasteBack.source_image = { image_name: initialImage.image_name };
|
||||
}
|
||||
|
||||
@@ -143,7 +142,7 @@ export const addInpaint = async (
|
||||
|
||||
g.addEdge(l2i, 'image', canvasPasteBack, 'generated_image');
|
||||
|
||||
if (!sendToCanvas) {
|
||||
if (!canvasSettings.sendToCanvas || canvasSettings.compositeMaskedRegions) {
|
||||
canvasPasteBack.source_image = { image_name: initialImage.image_name };
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ export const addOutpaint = async (
|
||||
const canvas = selectCanvasSlice(state);
|
||||
|
||||
const { bbox } = canvas;
|
||||
const { sendToCanvas } = canvasSettings;
|
||||
|
||||
const initialImage = await manager.compositor.getCompositeRasterLayerImageDTO(bbox.rect);
|
||||
const maskImage = await manager.compositor.getCompositeInpaintMaskImageDTO(bbox.rect);
|
||||
@@ -123,7 +122,7 @@ export const addOutpaint = async (
|
||||
g.addEdge(resizeOutputImageToOriginalSize, 'image', canvasPasteBack, 'generated_image');
|
||||
g.addEdge(resizeOutputMaskToOriginalSize, 'image', canvasPasteBack, 'mask');
|
||||
|
||||
if (!sendToCanvas) {
|
||||
if (!canvasSettings.sendToCanvas || canvasSettings.compositeMaskedRegions) {
|
||||
canvasPasteBack.source_image = { image_name: initialImage.image_name };
|
||||
}
|
||||
|
||||
@@ -173,7 +172,7 @@ export const addOutpaint = async (
|
||||
g.addEdge(createGradientMask, 'expanded_mask_area', canvasPasteBack, 'mask');
|
||||
g.addEdge(l2i, 'image', canvasPasteBack, 'generated_image');
|
||||
|
||||
if (!sendToCanvas) {
|
||||
if (!canvasSettings.sendToCanvas || canvasSettings.compositeMaskedRegions) {
|
||||
canvasPasteBack.source_image = { image_name: initialImage.image_name };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user