mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
NSFW checker and watermark nodes (#3923)
## What type of PR is this? (check all applicable) - [ ] Refactor - [ X] Feature - [ ] Bug Fix - [ ] Optimization - [ ] Documentation Update - [ ] Community Node Submission ## Have you discussed this change with the InvokeAI team? - [ X] Yes - [ ] No, because: ## Have you updated all relevant documentation? - [X ] Yes - [] No ## Description This PR adds NSFW checker and invisible watermark fields. The NSFW checker takes an image input and produces an image output. If NSFW content is detected, the output image will be blurred and a "caution" icon pasted into its upper left corner. A boolean `active` field controls whether the checker is active. If turned off it simply returns a copy of the image. The invisible watermark node adds an invisible text to the image, defaulting to "InvokeAI". To decode the watermark use the `invisible-watermark` command, which is part of the `invisible-watermark` library: ``` $ invisible-watermark -v -a decode -t bytes -m dwtDct -l 64 ./bluebird-watermark.png decode time ms: 14.129877090454102 InvokeAI ``` Note that the `-l` (length) argument is mandatory. It is set to 64 here because the watermark `InvokeAI` is 8 bytes/64 bits long. The length must match in order for the watermark to be decoded correctly. Both nodes are now incorporated into the linear Text2Image and Image2Image UIs, including the canvas. They are not implemented for inpaint currently. The nodes can be disabled with configuration options: ``` invisible_watermark: false nsfw_checker: false ``` or at launch time with `--no-invisible_watermark` and `--no-nsfw_checker`.
This commit is contained in:
169
invokeai/frontend/web/dist/assets/App-06ea4e5e.js
vendored
169
invokeai/frontend/web/dist/assets/App-06ea4e5e.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
125
invokeai/frontend/web/dist/assets/index-e2437518.js
vendored
125
invokeai/frontend/web/dist/assets/index-e2437518.js
vendored
File diff suppressed because one or more lines are too long
2
invokeai/frontend/web/dist/index.html
vendored
2
invokeai/frontend/web/dist/index.html
vendored
@ -12,7 +12,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<script type="module" crossorigin src="./assets/index-e2437518.js"></script>
|
||||
<script type="module" crossorigin src="./assets/index-e45bf5a6.js"></script>
|
||||
</head>
|
||||
|
||||
<body dir="ltr">
|
||||
|
15
invokeai/frontend/web/dist/locales/en.json
vendored
15
invokeai/frontend/web/dist/locales/en.json
vendored
@ -102,8 +102,7 @@
|
||||
"openInNewTab": "Open in New Tab",
|
||||
"dontAskMeAgain": "Don't ask me again",
|
||||
"areYouSure": "Are you sure?",
|
||||
"imagePrompt": "Image Prompt",
|
||||
"clearNodes": "Are you sure you want to clear all nodes?"
|
||||
"imagePrompt": "Image Prompt"
|
||||
},
|
||||
"gallery": {
|
||||
"generations": "Generations",
|
||||
@ -615,6 +614,11 @@
|
||||
"initialImageNotSetDesc": "Could not load initial image",
|
||||
"nodesSaved": "Nodes Saved",
|
||||
"nodesLoaded": "Nodes Loaded",
|
||||
"nodesNotValidGraph": "Not a valid InvokeAI Node Graph",
|
||||
"nodesNotValidJSON": "Not a valid JSON",
|
||||
"nodesCorruptedGraph": "Cannot load. Graph seems to be corrupted.",
|
||||
"nodesUnrecognizedTypes": "Cannot load. Graph has unrecognized types",
|
||||
"nodesBrokenConnections": "Cannot load. Some connections are broken.",
|
||||
"nodesLoadedFailed": "Failed To Load Nodes",
|
||||
"nodesCleared": "Nodes Cleared"
|
||||
},
|
||||
@ -700,9 +704,10 @@
|
||||
},
|
||||
"nodes": {
|
||||
"reloadSchema": "Reload Schema",
|
||||
"saveNodes": "Save Nodes",
|
||||
"loadNodes": "Load Nodes",
|
||||
"clearNodes": "Clear Nodes",
|
||||
"saveGraph": "Save Graph",
|
||||
"loadGraph": "Load Graph (saved from Node Editor) (Do not copy-paste metadata)",
|
||||
"clearGraph": "Clear Graph",
|
||||
"clearGraphDesc": "Are you sure you want to clear all nodes?",
|
||||
"zoomInNodes": "Zoom In",
|
||||
"zoomOutNodes": "Zoom Out",
|
||||
"fitViewportNodes": "Fit View",
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { setInfillMethod } from 'features/parameters/store/generationSlice';
|
||||
import {
|
||||
shouldUseNSFWCheckerChanged,
|
||||
shouldUseWatermarkerChanged,
|
||||
} from 'features/system/store/systemSlice';
|
||||
import { appInfoApi } from 'services/api/endpoints/appInfo';
|
||||
import { startAppListening } from '..';
|
||||
|
||||
@ -6,12 +10,21 @@ export const addAppConfigReceivedListener = () => {
|
||||
startAppListening({
|
||||
matcher: appInfoApi.endpoints.getAppConfig.matchFulfilled,
|
||||
effect: async (action, { getState, dispatch }) => {
|
||||
const { infill_methods } = action.payload;
|
||||
const { infill_methods, nsfw_methods, watermarking_methods } =
|
||||
action.payload;
|
||||
const infillMethod = getState().generation.infillMethod;
|
||||
|
||||
if (!infill_methods.includes(infillMethod)) {
|
||||
dispatch(setInfillMethod(infill_methods[0]));
|
||||
}
|
||||
|
||||
if (!nsfw_methods.includes('nsfw_checker')) {
|
||||
dispatch(shouldUseNSFWCheckerChanged(false));
|
||||
}
|
||||
|
||||
if (!watermarking_methods.includes('invisible_watermark')) {
|
||||
dispatch(shouldUseWatermarkerChanged(false));
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -1,13 +1,10 @@
|
||||
import { logger } from 'app/logging/logger';
|
||||
import { LIST_TAG } from 'services/api';
|
||||
import { appInfoApi } from 'services/api/endpoints/appInfo';
|
||||
import { modelsApi } from 'services/api/endpoints/models';
|
||||
import { receivedOpenAPISchema } from 'services/api/thunks/schema';
|
||||
import { appSocketConnected, socketConnected } from 'services/events/actions';
|
||||
import { startAppListening } from '../..';
|
||||
import {
|
||||
ALL_BASE_MODELS,
|
||||
NON_REFINER_BASE_MODELS,
|
||||
REFINER_BASE_MODELS,
|
||||
} from 'services/api/constants';
|
||||
|
||||
export const addSocketConnectedEventListener = () => {
|
||||
startAppListening({
|
||||
@ -29,15 +26,18 @@ export const addSocketConnectedEventListener = () => {
|
||||
dispatch(appSocketConnected(action.payload));
|
||||
|
||||
// update all server state
|
||||
dispatch(modelsApi.endpoints.getMainModels.initiate(REFINER_BASE_MODELS));
|
||||
dispatch(
|
||||
modelsApi.endpoints.getMainModels.initiate(NON_REFINER_BASE_MODELS)
|
||||
modelsApi.util.invalidateTags([
|
||||
{ type: 'MainModel', id: LIST_TAG },
|
||||
{ type: 'SDXLRefinerModel', id: LIST_TAG },
|
||||
{ type: 'LoRAModel', id: LIST_TAG },
|
||||
{ type: 'ControlNetModel', id: LIST_TAG },
|
||||
{ type: 'VaeModel', id: LIST_TAG },
|
||||
{ type: 'TextualInversionModel', id: LIST_TAG },
|
||||
{ type: 'ScannedModels', id: LIST_TAG },
|
||||
])
|
||||
);
|
||||
dispatch(modelsApi.endpoints.getMainModels.initiate(ALL_BASE_MODELS));
|
||||
dispatch(modelsApi.endpoints.getControlNetModels.initiate());
|
||||
dispatch(modelsApi.endpoints.getLoRAModels.initiate());
|
||||
dispatch(modelsApi.endpoints.getTextualInversionModels.initiate());
|
||||
dispatch(modelsApi.endpoints.getVaeModels.initiate());
|
||||
dispatch(appInfoApi.util.invalidateTags(['AppConfig', 'AppVersion']));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -5,8 +5,8 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
// import { validateSeedWeights } from 'common/util/seedWeightPairs';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import { forEach } from 'lodash-es';
|
||||
import { NON_REFINER_BASE_MODELS } from 'services/api/constants';
|
||||
import { modelsApi } from '../../services/api/endpoints/models';
|
||||
import { ALL_BASE_MODELS } from 'services/api/constants';
|
||||
|
||||
const readinessSelector = createSelector(
|
||||
[stateSelector, activeTabNameSelector],
|
||||
@ -25,7 +25,7 @@ const readinessSelector = createSelector(
|
||||
}
|
||||
|
||||
const { isSuccess: mainModelsSuccessfullyLoaded } =
|
||||
modelsApi.endpoints.getMainModels.select(ALL_BASE_MODELS)(state);
|
||||
modelsApi.endpoints.getMainModels.select(NON_REFINER_BASE_MODELS)(state);
|
||||
if (!mainModelsSuccessfullyLoaded) {
|
||||
isReady = false;
|
||||
reasonsWhyNotReady.push('Models are not loaded');
|
||||
|
@ -0,0 +1,70 @@
|
||||
import { RootState } from 'app/store/store';
|
||||
import { NonNullableGraph } from 'features/nodes/types/types';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import {
|
||||
ImageNSFWBlurInvocation,
|
||||
LatentsToImageInvocation,
|
||||
MetadataAccumulatorInvocation,
|
||||
} from 'services/api/types';
|
||||
import {
|
||||
LATENTS_TO_IMAGE,
|
||||
METADATA_ACCUMULATOR,
|
||||
NSFW_CHECKER,
|
||||
} from './constants';
|
||||
|
||||
export const addNSFWCheckerToGraph = (
|
||||
state: RootState,
|
||||
graph: NonNullableGraph,
|
||||
nodeIdToAddTo = LATENTS_TO_IMAGE
|
||||
): void => {
|
||||
const activeTabName = activeTabNameSelector(state);
|
||||
|
||||
const is_intermediate =
|
||||
activeTabName === 'unifiedCanvas' ? !state.canvas.shouldAutoSave : false;
|
||||
|
||||
const nodeToAddTo = graph.nodes[nodeIdToAddTo] as
|
||||
| LatentsToImageInvocation
|
||||
| undefined;
|
||||
|
||||
const metadataAccumulator = graph.nodes[METADATA_ACCUMULATOR] as
|
||||
| MetadataAccumulatorInvocation
|
||||
| undefined;
|
||||
|
||||
if (!nodeToAddTo) {
|
||||
// something has gone terribly awry
|
||||
return;
|
||||
}
|
||||
|
||||
nodeToAddTo.is_intermediate = true;
|
||||
|
||||
const nsfwCheckerNode: ImageNSFWBlurInvocation = {
|
||||
id: NSFW_CHECKER,
|
||||
type: 'img_nsfw',
|
||||
is_intermediate,
|
||||
};
|
||||
|
||||
graph.nodes[NSFW_CHECKER] = nsfwCheckerNode;
|
||||
graph.edges.push({
|
||||
source: {
|
||||
node_id: nodeIdToAddTo,
|
||||
field: 'image',
|
||||
},
|
||||
destination: {
|
||||
node_id: NSFW_CHECKER,
|
||||
field: 'image',
|
||||
},
|
||||
});
|
||||
|
||||
if (metadataAccumulator) {
|
||||
graph.edges.push({
|
||||
source: {
|
||||
node_id: METADATA_ACCUMULATOR,
|
||||
field: 'metadata',
|
||||
},
|
||||
destination: {
|
||||
node_id: NSFW_CHECKER,
|
||||
field: 'metadata',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
@ -0,0 +1,95 @@
|
||||
import { RootState } from 'app/store/store';
|
||||
import { NonNullableGraph } from 'features/nodes/types/types';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import {
|
||||
ImageNSFWBlurInvocation,
|
||||
ImageWatermarkInvocation,
|
||||
LatentsToImageInvocation,
|
||||
MetadataAccumulatorInvocation,
|
||||
} from 'services/api/types';
|
||||
import {
|
||||
LATENTS_TO_IMAGE,
|
||||
METADATA_ACCUMULATOR,
|
||||
NSFW_CHECKER,
|
||||
WATERMARKER,
|
||||
} from './constants';
|
||||
|
||||
export const addWatermarkerToGraph = (
|
||||
state: RootState,
|
||||
graph: NonNullableGraph,
|
||||
nodeIdToAddTo = LATENTS_TO_IMAGE
|
||||
): void => {
|
||||
const activeTabName = activeTabNameSelector(state);
|
||||
|
||||
const is_intermediate =
|
||||
activeTabName === 'unifiedCanvas' ? !state.canvas.shouldAutoSave : false;
|
||||
|
||||
const nodeToAddTo = graph.nodes[nodeIdToAddTo] as
|
||||
| LatentsToImageInvocation
|
||||
| undefined;
|
||||
|
||||
const nsfwCheckerNode = graph.nodes[NSFW_CHECKER] as
|
||||
| ImageNSFWBlurInvocation
|
||||
| undefined;
|
||||
|
||||
const metadataAccumulator = graph.nodes[METADATA_ACCUMULATOR] as
|
||||
| MetadataAccumulatorInvocation
|
||||
| undefined;
|
||||
|
||||
if (!nodeToAddTo) {
|
||||
// something has gone terribly awry
|
||||
return;
|
||||
}
|
||||
|
||||
const watermarkerNode: ImageWatermarkInvocation = {
|
||||
id: WATERMARKER,
|
||||
type: 'img_watermark',
|
||||
is_intermediate,
|
||||
};
|
||||
|
||||
graph.nodes[WATERMARKER] = watermarkerNode;
|
||||
|
||||
// no matter the situation, we want the l2i node to be intermediate
|
||||
nodeToAddTo.is_intermediate = true;
|
||||
|
||||
if (nsfwCheckerNode) {
|
||||
// if we are using NSFW checker, we need to "disable" it output by marking it intermediate,
|
||||
// then connect it to the watermark node
|
||||
nsfwCheckerNode.is_intermediate = true;
|
||||
graph.edges.push({
|
||||
source: {
|
||||
node_id: NSFW_CHECKER,
|
||||
field: 'image',
|
||||
},
|
||||
destination: {
|
||||
node_id: WATERMARKER,
|
||||
field: 'image',
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// otherwise we just connect to the watermark node
|
||||
graph.edges.push({
|
||||
source: {
|
||||
node_id: nodeIdToAddTo,
|
||||
field: 'image',
|
||||
},
|
||||
destination: {
|
||||
node_id: WATERMARKER,
|
||||
field: 'image',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (metadataAccumulator) {
|
||||
graph.edges.push({
|
||||
source: {
|
||||
node_id: METADATA_ACCUMULATOR,
|
||||
field: 'metadata',
|
||||
},
|
||||
destination: {
|
||||
node_id: WATERMARKER,
|
||||
field: 'metadata',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
@ -10,7 +10,9 @@ import {
|
||||
import { addControlNetToLinearGraph } from './addControlNetToLinearGraph';
|
||||
import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph';
|
||||
import { addLoRAsToGraph } from './addLoRAsToGraph';
|
||||
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
|
||||
import { addVAEToGraph } from './addVAEToGraph';
|
||||
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
|
||||
import {
|
||||
CLIP_SKIP,
|
||||
IMAGE_TO_IMAGE_GRAPH,
|
||||
@ -103,11 +105,6 @@ export const buildCanvasImageToImageGraph = (
|
||||
is_intermediate: true,
|
||||
skipped_layers: clipSkip,
|
||||
},
|
||||
[LATENTS_TO_IMAGE]: {
|
||||
is_intermediate: !shouldAutoSave,
|
||||
type: 'l2i',
|
||||
id: LATENTS_TO_IMAGE,
|
||||
},
|
||||
[LATENTS_TO_LATENTS]: {
|
||||
type: 'l2l',
|
||||
id: LATENTS_TO_LATENTS,
|
||||
@ -126,6 +123,11 @@ export const buildCanvasImageToImageGraph = (
|
||||
// image_name: initialImage.image_name,
|
||||
// },
|
||||
},
|
||||
[LATENTS_TO_IMAGE]: {
|
||||
type: 'l2i',
|
||||
id: LATENTS_TO_IMAGE,
|
||||
is_intermediate: !shouldAutoSave,
|
||||
},
|
||||
},
|
||||
edges: [
|
||||
{
|
||||
@ -310,17 +312,6 @@ export const buildCanvasImageToImageGraph = (
|
||||
init_image: initialImage.image_name,
|
||||
};
|
||||
|
||||
graph.edges.push({
|
||||
source: {
|
||||
node_id: METADATA_ACCUMULATOR,
|
||||
field: 'metadata',
|
||||
},
|
||||
destination: {
|
||||
node_id: LATENTS_TO_IMAGE,
|
||||
field: 'metadata',
|
||||
},
|
||||
});
|
||||
|
||||
// add LoRA support
|
||||
addLoRAsToGraph(state, graph, LATENTS_TO_LATENTS);
|
||||
|
||||
@ -333,5 +324,16 @@ export const buildCanvasImageToImageGraph = (
|
||||
// add controlnet, mutating `graph`
|
||||
addControlNetToLinearGraph(state, graph, LATENTS_TO_LATENTS);
|
||||
|
||||
// NSFW & watermark - must be last thing added to graph
|
||||
if (state.system.shouldUseNSFWChecker) {
|
||||
// must add before watermarker!
|
||||
addNSFWCheckerToGraph(state, graph);
|
||||
}
|
||||
|
||||
if (state.system.shouldUseWatermarker) {
|
||||
// must add after nsfw checker!
|
||||
addWatermarkerToGraph(state, graph);
|
||||
}
|
||||
|
||||
return graph;
|
||||
};
|
||||
|
@ -20,6 +20,8 @@ import {
|
||||
RANDOM_INT,
|
||||
RANGE_OF_SIZE,
|
||||
} from './constants';
|
||||
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
|
||||
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
|
||||
|
||||
/**
|
||||
* Builds the Canvas tab's Inpaint graph.
|
||||
@ -249,5 +251,16 @@ export const buildCanvasInpaintGraph = (
|
||||
(graph.nodes[RANGE_OF_SIZE] as RangeOfSizeInvocation).start = seed;
|
||||
}
|
||||
|
||||
// NSFW & watermark - must be last thing added to graph
|
||||
if (state.system.shouldUseNSFWChecker) {
|
||||
// must add before watermarker!
|
||||
addNSFWCheckerToGraph(state, graph, INPAINT);
|
||||
}
|
||||
|
||||
if (state.system.shouldUseWatermarker) {
|
||||
// must add after nsfw checker!
|
||||
addWatermarkerToGraph(state, graph, INPAINT);
|
||||
}
|
||||
|
||||
return graph;
|
||||
};
|
||||
|
@ -5,7 +5,9 @@ import { initialGenerationState } from 'features/parameters/store/generationSlic
|
||||
import { addControlNetToLinearGraph } from './addControlNetToLinearGraph';
|
||||
import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph';
|
||||
import { addLoRAsToGraph } from './addLoRAsToGraph';
|
||||
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
|
||||
import { addVAEToGraph } from './addVAEToGraph';
|
||||
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
|
||||
import {
|
||||
CLIP_SKIP,
|
||||
LATENTS_TO_IMAGE,
|
||||
@ -215,17 +217,6 @@ export const buildCanvasTextToImageGraph = (
|
||||
clip_skip: clipSkip,
|
||||
};
|
||||
|
||||
graph.edges.push({
|
||||
source: {
|
||||
node_id: METADATA_ACCUMULATOR,
|
||||
field: 'metadata',
|
||||
},
|
||||
destination: {
|
||||
node_id: LATENTS_TO_IMAGE,
|
||||
field: 'metadata',
|
||||
},
|
||||
});
|
||||
|
||||
// add LoRA support
|
||||
addLoRAsToGraph(state, graph, TEXT_TO_LATENTS);
|
||||
|
||||
@ -238,5 +229,16 @@ export const buildCanvasTextToImageGraph = (
|
||||
// add controlnet, mutating `graph`
|
||||
addControlNetToLinearGraph(state, graph, TEXT_TO_LATENTS);
|
||||
|
||||
// NSFW & watermark - must be last thing added to graph
|
||||
if (state.system.shouldUseNSFWChecker) {
|
||||
// must add before watermarker!
|
||||
addNSFWCheckerToGraph(state, graph);
|
||||
}
|
||||
|
||||
if (state.system.shouldUseWatermarker) {
|
||||
// must add after nsfw checker!
|
||||
addWatermarkerToGraph(state, graph);
|
||||
}
|
||||
|
||||
return graph;
|
||||
};
|
||||
|
@ -9,7 +9,9 @@ import {
|
||||
import { addControlNetToLinearGraph } from './addControlNetToLinearGraph';
|
||||
import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph';
|
||||
import { addLoRAsToGraph } from './addLoRAsToGraph';
|
||||
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
|
||||
import { addVAEToGraph } from './addVAEToGraph';
|
||||
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
|
||||
import {
|
||||
CLIP_SKIP,
|
||||
IMAGE_TO_IMAGE_GRAPH,
|
||||
@ -297,42 +299,6 @@ export const buildLinearImageToImageGraph = (
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: add batch functionality
|
||||
// if (isBatchEnabled && asInitialImage && batchImageNames.length > 0) {
|
||||
// // we are going to connect an iterate up to the init image
|
||||
// delete (graph.nodes[IMAGE_TO_LATENTS] as ImageToLatentsInvocation).image;
|
||||
|
||||
// const imageCollection: ImageCollectionInvocation = {
|
||||
// id: IMAGE_COLLECTION,
|
||||
// type: 'image_collection',
|
||||
// images: batchImageNames.map((image_name) => ({ image_name })),
|
||||
// };
|
||||
|
||||
// const imageCollectionIterate: IterateInvocation = {
|
||||
// id: IMAGE_COLLECTION_ITERATE,
|
||||
// type: 'iterate',
|
||||
// };
|
||||
|
||||
// graph.nodes[IMAGE_COLLECTION] = imageCollection;
|
||||
// graph.nodes[IMAGE_COLLECTION_ITERATE] = imageCollectionIterate;
|
||||
|
||||
// graph.edges.push({
|
||||
// source: { node_id: IMAGE_COLLECTION, field: 'collection' },
|
||||
// destination: {
|
||||
// node_id: IMAGE_COLLECTION_ITERATE,
|
||||
// field: 'collection',
|
||||
// },
|
||||
// });
|
||||
|
||||
// graph.edges.push({
|
||||
// source: { node_id: IMAGE_COLLECTION_ITERATE, field: 'item' },
|
||||
// destination: {
|
||||
// node_id: IMAGE_TO_LATENTS,
|
||||
// field: 'image',
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
// add metadata accumulator, which is only mostly populated - some fields are added later
|
||||
graph.nodes[METADATA_ACCUMULATOR] = {
|
||||
id: METADATA_ACCUMULATOR,
|
||||
@ -356,17 +322,6 @@ export const buildLinearImageToImageGraph = (
|
||||
init_image: initialImage.imageName,
|
||||
};
|
||||
|
||||
graph.edges.push({
|
||||
source: {
|
||||
node_id: METADATA_ACCUMULATOR,
|
||||
field: 'metadata',
|
||||
},
|
||||
destination: {
|
||||
node_id: LATENTS_TO_IMAGE,
|
||||
field: 'metadata',
|
||||
},
|
||||
});
|
||||
|
||||
// add LoRA support
|
||||
addLoRAsToGraph(state, graph, LATENTS_TO_LATENTS);
|
||||
|
||||
@ -379,5 +334,16 @@ export const buildLinearImageToImageGraph = (
|
||||
// add controlnet, mutating `graph`
|
||||
addControlNetToLinearGraph(state, graph, LATENTS_TO_LATENTS);
|
||||
|
||||
// NSFW & watermark - must be last thing added to graph
|
||||
if (state.system.shouldUseNSFWChecker) {
|
||||
// must add before watermarker!
|
||||
addNSFWCheckerToGraph(state, graph);
|
||||
}
|
||||
|
||||
if (state.system.shouldUseWatermarker) {
|
||||
// must add after nsfw checker!
|
||||
addWatermarkerToGraph(state, graph);
|
||||
}
|
||||
|
||||
return graph;
|
||||
};
|
||||
|
@ -20,6 +20,8 @@ import {
|
||||
SDXL_LATENTS_TO_LATENTS,
|
||||
SDXL_MODEL_LOADER,
|
||||
} from './constants';
|
||||
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
|
||||
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
|
||||
|
||||
/**
|
||||
* Builds the Image to Image tab graph.
|
||||
@ -365,5 +367,16 @@ export const buildLinearSDXLImageToImageGraph = (
|
||||
// add dynamic prompts - also sets up core iteration and seed
|
||||
addDynamicPromptsToGraph(state, graph);
|
||||
|
||||
// NSFW & watermark - must be last thing added to graph
|
||||
if (state.system.shouldUseNSFWChecker) {
|
||||
// must add before watermarker!
|
||||
addNSFWCheckerToGraph(state, graph);
|
||||
}
|
||||
|
||||
if (state.system.shouldUseWatermarker) {
|
||||
// must add after nsfw checker!
|
||||
addWatermarkerToGraph(state, graph);
|
||||
}
|
||||
|
||||
return graph;
|
||||
};
|
||||
|
@ -14,6 +14,8 @@ import {
|
||||
SDXL_TEXT_TO_IMAGE_GRAPH,
|
||||
SDXL_TEXT_TO_LATENTS,
|
||||
} from './constants';
|
||||
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
|
||||
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
|
||||
|
||||
export const buildLinearSDXLTextToImageGraph = (
|
||||
state: RootState
|
||||
@ -247,5 +249,16 @@ export const buildLinearSDXLTextToImageGraph = (
|
||||
// add dynamic prompts - also sets up core iteration and seed
|
||||
addDynamicPromptsToGraph(state, graph);
|
||||
|
||||
// NSFW & watermark - must be last thing added to graph
|
||||
if (state.system.shouldUseNSFWChecker) {
|
||||
// must add before watermarker!
|
||||
addNSFWCheckerToGraph(state, graph);
|
||||
}
|
||||
|
||||
if (state.system.shouldUseWatermarker) {
|
||||
// must add after nsfw checker!
|
||||
addWatermarkerToGraph(state, graph);
|
||||
}
|
||||
|
||||
return graph;
|
||||
};
|
||||
|
@ -5,7 +5,9 @@ import { initialGenerationState } from 'features/parameters/store/generationSlic
|
||||
import { addControlNetToLinearGraph } from './addControlNetToLinearGraph';
|
||||
import { addDynamicPromptsToGraph } from './addDynamicPromptsToGraph';
|
||||
import { addLoRAsToGraph } from './addLoRAsToGraph';
|
||||
import { addNSFWCheckerToGraph } from './addNSFWCheckerToGraph';
|
||||
import { addVAEToGraph } from './addVAEToGraph';
|
||||
import { addWatermarkerToGraph } from './addWatermarkerToGraph';
|
||||
import {
|
||||
CLIP_SKIP,
|
||||
LATENTS_TO_IMAGE,
|
||||
@ -204,17 +206,6 @@ export const buildLinearTextToImageGraph = (
|
||||
clip_skip: clipSkip,
|
||||
};
|
||||
|
||||
graph.edges.push({
|
||||
source: {
|
||||
node_id: METADATA_ACCUMULATOR,
|
||||
field: 'metadata',
|
||||
},
|
||||
destination: {
|
||||
node_id: LATENTS_TO_IMAGE,
|
||||
field: 'metadata',
|
||||
},
|
||||
});
|
||||
|
||||
// add LoRA support
|
||||
addLoRAsToGraph(state, graph, TEXT_TO_LATENTS);
|
||||
|
||||
@ -227,5 +218,16 @@ export const buildLinearTextToImageGraph = (
|
||||
// add controlnet, mutating `graph`
|
||||
addControlNetToLinearGraph(state, graph, TEXT_TO_LATENTS);
|
||||
|
||||
// NSFW & watermark - must be last thing added to graph
|
||||
if (state.system.shouldUseNSFWChecker) {
|
||||
// must add before watermarker!
|
||||
addNSFWCheckerToGraph(state, graph);
|
||||
}
|
||||
|
||||
if (state.system.shouldUseWatermarker) {
|
||||
// must add after nsfw checker!
|
||||
addWatermarkerToGraph(state, graph);
|
||||
}
|
||||
|
||||
return graph;
|
||||
};
|
||||
|
@ -3,6 +3,8 @@ export const POSITIVE_CONDITIONING = 'positive_conditioning';
|
||||
export const NEGATIVE_CONDITIONING = 'negative_conditioning';
|
||||
export const TEXT_TO_LATENTS = 'text_to_latents';
|
||||
export const LATENTS_TO_IMAGE = 'latents_to_image';
|
||||
export const NSFW_CHECKER = 'nsfw_checker';
|
||||
export const WATERMARKER = 'invisible_watermark';
|
||||
export const NOISE = 'noise';
|
||||
export const RANDOM_INT = 'rand_int';
|
||||
export const RANGE_OF_SIZE = 'range_of_size';
|
||||
|
@ -27,6 +27,8 @@ import {
|
||||
setShouldConfirmOnDelete,
|
||||
shouldAntialiasProgressImageChanged,
|
||||
shouldLogToConsoleChanged,
|
||||
shouldUseNSFWCheckerChanged,
|
||||
shouldUseWatermarkerChanged,
|
||||
} from 'features/system/store/systemSlice';
|
||||
import {
|
||||
setShouldShowProgressInViewer,
|
||||
@ -43,6 +45,7 @@ import {
|
||||
} from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { LogLevelName } from 'roarr';
|
||||
import { useGetAppConfigQuery } from 'services/api/endpoints/appInfo';
|
||||
import SettingSwitch from './SettingSwitch';
|
||||
import SettingsClearIntermediates from './SettingsClearIntermediates';
|
||||
import SettingsSchedulers from './SettingsSchedulers';
|
||||
@ -62,6 +65,8 @@ const selector = createSelector(
|
||||
shouldLogToConsole,
|
||||
shouldAntialiasProgressImage,
|
||||
isNodesEnabled,
|
||||
shouldUseNSFWChecker,
|
||||
shouldUseWatermarker,
|
||||
} = system;
|
||||
|
||||
const {
|
||||
@ -83,6 +88,8 @@ const selector = createSelector(
|
||||
shouldAntialiasProgressImage,
|
||||
shouldShowAdvancedOptions,
|
||||
isNodesEnabled,
|
||||
shouldUseNSFWChecker,
|
||||
shouldUseWatermarker,
|
||||
};
|
||||
},
|
||||
{
|
||||
@ -125,6 +132,16 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
|
||||
}
|
||||
}, [shouldShowDeveloperSettings, dispatch]);
|
||||
|
||||
const { isNSFWCheckerAvailable, isWatermarkerAvailable } =
|
||||
useGetAppConfigQuery(undefined, {
|
||||
selectFromResult: ({ data }) => ({
|
||||
isNSFWCheckerAvailable:
|
||||
data?.nsfw_methods.includes('nsfw_checker') ?? false,
|
||||
isWatermarkerAvailable:
|
||||
data?.watermarking_methods.includes('invisible_watermark') ?? false,
|
||||
}),
|
||||
});
|
||||
|
||||
const {
|
||||
isOpen: isSettingsModalOpen,
|
||||
onOpen: onSettingsModalOpen,
|
||||
@ -148,6 +165,8 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
|
||||
shouldAntialiasProgressImage,
|
||||
shouldShowAdvancedOptions,
|
||||
isNodesEnabled,
|
||||
shouldUseNSFWChecker,
|
||||
shouldUseWatermarker,
|
||||
} = useAppSelector(selector);
|
||||
|
||||
const handleClickResetWebUI = useCallback(() => {
|
||||
@ -239,6 +258,22 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
|
||||
<StyledFlex>
|
||||
<Heading size="sm">{t('settings.generation')}</Heading>
|
||||
<SettingsSchedulers />
|
||||
<SettingSwitch
|
||||
label="Enable NSFW Checker"
|
||||
isDisabled={!isNSFWCheckerAvailable}
|
||||
isChecked={shouldUseNSFWChecker}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
dispatch(shouldUseNSFWCheckerChanged(e.target.checked))
|
||||
}
|
||||
/>
|
||||
<SettingSwitch
|
||||
label="Enable Invisible Watermark"
|
||||
isDisabled={!isWatermarkerAvailable}
|
||||
isChecked={shouldUseWatermarker}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
dispatch(shouldUseWatermarkerChanged(e.target.checked))
|
||||
}
|
||||
/>
|
||||
</StyledFlex>
|
||||
|
||||
<StyledFlex>
|
||||
|
@ -87,6 +87,8 @@ export interface SystemState {
|
||||
language: keyof typeof LANGUAGES;
|
||||
isUploading: boolean;
|
||||
isNodesEnabled: boolean;
|
||||
shouldUseNSFWChecker: boolean;
|
||||
shouldUseWatermarker: boolean;
|
||||
}
|
||||
|
||||
export const initialSystemState: SystemState = {
|
||||
@ -119,6 +121,8 @@ export const initialSystemState: SystemState = {
|
||||
language: 'en',
|
||||
isUploading: false,
|
||||
isNodesEnabled: false,
|
||||
shouldUseNSFWChecker: false,
|
||||
shouldUseWatermarker: false,
|
||||
};
|
||||
|
||||
export const systemSlice = createSlice({
|
||||
@ -194,6 +198,12 @@ export const systemSlice = createSlice({
|
||||
setIsNodesEnabled(state, action: PayloadAction<boolean>) {
|
||||
state.isNodesEnabled = action.payload;
|
||||
},
|
||||
shouldUseNSFWCheckerChanged(state, action: PayloadAction<boolean>) {
|
||||
state.shouldUseNSFWChecker = action.payload;
|
||||
},
|
||||
shouldUseWatermarkerChanged(state, action: PayloadAction<boolean>) {
|
||||
state.shouldUseWatermarker = action.payload;
|
||||
},
|
||||
},
|
||||
extraReducers(builder) {
|
||||
/**
|
||||
@ -409,6 +419,8 @@ export const {
|
||||
languageChanged,
|
||||
progressImageSet,
|
||||
setIsNodesEnabled,
|
||||
shouldUseNSFWCheckerChanged,
|
||||
shouldUseWatermarkerChanged,
|
||||
} = systemSlice.actions;
|
||||
|
||||
export default systemSlice.reducer;
|
||||
|
@ -8,6 +8,7 @@ export const appInfoApi = api.injectEndpoints({
|
||||
url: `app/version`,
|
||||
method: 'GET',
|
||||
}),
|
||||
providesTags: ['AppVersion'],
|
||||
keepUnusedDataFor: 86400000, // 1 day
|
||||
}),
|
||||
getAppConfig: build.query<AppConfig, void>({
|
||||
@ -15,6 +16,7 @@ export const appInfoApi = api.injectEndpoints({
|
||||
url: `app/config`,
|
||||
method: 'GET',
|
||||
}),
|
||||
providesTags: ['AppConfig'],
|
||||
keepUnusedDataFor: 86400000, // 1 day
|
||||
}),
|
||||
}),
|
||||
|
108
invokeai/frontend/web/src/services/api/schema.d.ts
vendored
108
invokeai/frontend/web/src/services/api/schema.d.ts
vendored
@ -318,6 +318,21 @@ export type components = {
|
||||
* @description List of available infill methods
|
||||
*/
|
||||
infill_methods: (string)[];
|
||||
/**
|
||||
* Upscaling Methods
|
||||
* @description List of upscaling methods
|
||||
*/
|
||||
upscaling_methods: (components["schemas"]["Upscaler"])[];
|
||||
/**
|
||||
* Nsfw Methods
|
||||
* @description List of NSFW checking methods
|
||||
*/
|
||||
nsfw_methods: (string)[];
|
||||
/**
|
||||
* Watermarking Methods
|
||||
* @description List of invisible watermark methods
|
||||
*/
|
||||
watermarking_methods: (string)[];
|
||||
};
|
||||
/**
|
||||
* AppVersion
|
||||
@ -1345,7 +1360,7 @@ export type components = {
|
||||
* @description The nodes in this graph
|
||||
*/
|
||||
nodes?: {
|
||||
[key: string]: (components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"]) | undefined;
|
||||
[key: string]: (components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"]) | undefined;
|
||||
};
|
||||
/**
|
||||
* Edges
|
||||
@ -1935,6 +1950,39 @@ export type components = {
|
||||
*/
|
||||
image2?: components["schemas"]["ImageField"];
|
||||
};
|
||||
/**
|
||||
* ImageNSFWBlurInvocation
|
||||
* @description Add blur to NSFW-flagged images
|
||||
*/
|
||||
ImageNSFWBlurInvocation: {
|
||||
/**
|
||||
* Id
|
||||
* @description The id of this node. Must be unique among all nodes.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Is Intermediate
|
||||
* @description Whether or not this node is an intermediate node.
|
||||
* @default false
|
||||
*/
|
||||
is_intermediate?: boolean;
|
||||
/**
|
||||
* Type
|
||||
* @default img_nsfw
|
||||
* @enum {string}
|
||||
*/
|
||||
type?: "img_nsfw";
|
||||
/**
|
||||
* Image
|
||||
* @description The image to check
|
||||
*/
|
||||
image?: components["schemas"]["ImageField"];
|
||||
/**
|
||||
* Metadata
|
||||
* @description Optional core metadata to be written to the image
|
||||
*/
|
||||
metadata?: components["schemas"]["CoreMetadata"];
|
||||
};
|
||||
/**
|
||||
* ImageOutput
|
||||
* @description Base class for invocations that output an image
|
||||
@ -2215,6 +2263,45 @@ export type components = {
|
||||
*/
|
||||
thumbnail_url: string;
|
||||
};
|
||||
/**
|
||||
* ImageWatermarkInvocation
|
||||
* @description Add an invisible watermark to an image
|
||||
*/
|
||||
ImageWatermarkInvocation: {
|
||||
/**
|
||||
* Id
|
||||
* @description The id of this node. Must be unique among all nodes.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Is Intermediate
|
||||
* @description Whether or not this node is an intermediate node.
|
||||
* @default false
|
||||
*/
|
||||
is_intermediate?: boolean;
|
||||
/**
|
||||
* Type
|
||||
* @default img_watermark
|
||||
* @enum {string}
|
||||
*/
|
||||
type?: "img_watermark";
|
||||
/**
|
||||
* Image
|
||||
* @description The image to check
|
||||
*/
|
||||
image?: components["schemas"]["ImageField"];
|
||||
/**
|
||||
* Text
|
||||
* @description Watermark text
|
||||
* @default InvokeAI
|
||||
*/
|
||||
text?: string;
|
||||
/**
|
||||
* Metadata
|
||||
* @description Optional core metadata to be written to the image
|
||||
*/
|
||||
metadata?: components["schemas"]["CoreMetadata"];
|
||||
};
|
||||
/**
|
||||
* InfillColorInvocation
|
||||
* @description Infills transparent areas of an image with a solid color
|
||||
@ -2644,7 +2731,7 @@ export type components = {
|
||||
vae?: components["schemas"]["VaeField"];
|
||||
/**
|
||||
* Tiled
|
||||
* @description Decode latents by overlaping tiles(less memory consumption)
|
||||
* @description Decode latents by overlapping tiles(less memory consumption)
|
||||
* @default false
|
||||
*/
|
||||
tiled?: boolean;
|
||||
@ -5309,6 +5396,19 @@ export type components = {
|
||||
*/
|
||||
loras: (components["schemas"]["LoraInfo"])[];
|
||||
};
|
||||
/** Upscaler */
|
||||
Upscaler: {
|
||||
/**
|
||||
* Upscaling Method
|
||||
* @description Name of upscaling method
|
||||
*/
|
||||
upscaling_method: string;
|
||||
/**
|
||||
* Upscaling Models
|
||||
* @description List of upscaling models for this method
|
||||
*/
|
||||
upscaling_models: (string)[];
|
||||
};
|
||||
/**
|
||||
* VAEModelField
|
||||
* @description Vae model field
|
||||
@ -5563,7 +5663,7 @@ export type operations = {
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
|
||||
"application/json": components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
@ -5600,7 +5700,7 @@ export type operations = {
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
|
||||
"application/json": components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
|
@ -134,6 +134,12 @@ export type ESRGANInvocation = TypeReq<
|
||||
export type DivideInvocation = TypeReq<
|
||||
components['schemas']['DivideInvocation']
|
||||
>;
|
||||
export type ImageNSFWBlurInvocation = TypeReq<
|
||||
components['schemas']['ImageNSFWBlurInvocation']
|
||||
>;
|
||||
export type ImageWatermarkInvocation = TypeReq<
|
||||
components['schemas']['ImageWatermarkInvocation']
|
||||
>;
|
||||
|
||||
// ControlNet Nodes
|
||||
export type ControlNetInvocation = TypeReq<
|
||||
|
Reference in New Issue
Block a user