mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Implements invert mask
This commit is contained in:
parent
7f0fb47cf3
commit
7075a17091
@ -12,7 +12,7 @@ import os
|
||||
from werkzeug.utils import secure_filename
|
||||
from flask import Flask, redirect, send_from_directory, flash, request, url_for, jsonify
|
||||
from flask_socketio import SocketIO
|
||||
from PIL import Image
|
||||
from PIL import Image, ImageOps
|
||||
from PIL.Image import Image as ImageType
|
||||
from uuid import uuid4
|
||||
from threading import Event
|
||||
@ -698,11 +698,11 @@ class InvokeAIWebServer:
|
||||
|
||||
So we need to convert each into a PIL Image.
|
||||
"""
|
||||
truncated_outpaint_image_b64 = generation_parameters["init_img"][:64]
|
||||
truncated_outpaint_mask_b64 = generation_parameters["init_mask"][:64]
|
||||
|
||||
init_img_url = generation_parameters["init_img"]
|
||||
|
||||
init_img_url = generation_parameters["init_img"]
|
||||
init_mask_url = generation_parameters["init_mask"]
|
||||
|
||||
init_img_path = self.get_image_path_from_url(init_img_url)
|
||||
|
||||
@ -723,6 +723,9 @@ class InvokeAIWebServer:
|
||||
generation_parameters["init_mask"]
|
||||
).convert("L")
|
||||
|
||||
if generation_parameters.invert_mask:
|
||||
mask_image = ImageOps.invert(mask_image)
|
||||
|
||||
"""
|
||||
Apply the mask to the init image, creating a "mask" image with
|
||||
transparency where inpainting should occur. This is the kind of
|
||||
|
@ -118,6 +118,7 @@ export const frontendToBackendParameters = (
|
||||
shouldUseInpaintReplace,
|
||||
stageScale,
|
||||
isMaskEnabled,
|
||||
shouldInvertMask,
|
||||
} = canvasState[canvasState.currentCanvas];
|
||||
|
||||
const boundingBox = {
|
||||
@ -137,6 +138,10 @@ export const frontendToBackendParameters = (
|
||||
generationParameters.init_img = imageToProcessUrl;
|
||||
generationParameters.strength = img2imgStrength;
|
||||
|
||||
if (shouldInvertMask) {
|
||||
generationParameters.invert_mask = true;
|
||||
}
|
||||
|
||||
if (shouldUseInpaintReplace) {
|
||||
generationParameters.inpaint_replace = inpaintReplace;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
setIsMaskEnabled,
|
||||
setLayer,
|
||||
setMaskColor,
|
||||
setShouldInvertMask,
|
||||
} from './canvasSlice';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store';
|
||||
import _ from 'lodash';
|
||||
@ -19,12 +20,13 @@ import IAIButton from 'common/components/IAIButton';
|
||||
export const selector = createSelector(
|
||||
[currentCanvasSelector],
|
||||
(currentCanvas) => {
|
||||
const { maskColor, layer, isMaskEnabled } = currentCanvas;
|
||||
const { maskColor, layer, isMaskEnabled, shouldInvertMask } = currentCanvas;
|
||||
|
||||
return {
|
||||
layer,
|
||||
maskColor,
|
||||
isMaskEnabled,
|
||||
shouldInvertMask,
|
||||
};
|
||||
},
|
||||
{
|
||||
@ -35,7 +37,8 @@ export const selector = createSelector(
|
||||
);
|
||||
const IAICanvasMaskButtonPopover = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { layer, maskColor, isMaskEnabled } = useAppSelector(selector);
|
||||
const { layer, maskColor, isMaskEnabled, shouldInvertMask } =
|
||||
useAppSelector(selector);
|
||||
|
||||
return (
|
||||
<IAIPopover
|
||||
@ -57,7 +60,11 @@ const IAICanvasMaskButtonPopover = () => {
|
||||
isChecked={isMaskEnabled}
|
||||
onChange={(e) => dispatch(setIsMaskEnabled(e.target.checked))}
|
||||
/>
|
||||
<IAICheckbox label="Invert Mask" />
|
||||
<IAICheckbox
|
||||
label="Invert Mask"
|
||||
isChecked={shouldInvertMask}
|
||||
onChange={(e) => dispatch(setShouldInvertMask(e.target.checked))}
|
||||
/>
|
||||
<IAIColorPicker
|
||||
color={maskColor}
|
||||
onChange={(newColor) => dispatch(setMaskColor(newColor))}
|
||||
|
@ -15,14 +15,20 @@ import Konva from 'konva';
|
||||
export const canvasMaskCompositerSelector = createSelector(
|
||||
currentCanvasSelector,
|
||||
(currentCanvas) => {
|
||||
const { maskColor, stageCoordinates, stageDimensions, stageScale } =
|
||||
currentCanvas as InpaintingCanvasState | OutpaintingCanvasState;
|
||||
const {
|
||||
maskColor,
|
||||
stageCoordinates,
|
||||
stageDimensions,
|
||||
stageScale,
|
||||
shouldInvertMask,
|
||||
} = currentCanvas as InpaintingCanvasState | OutpaintingCanvasState;
|
||||
|
||||
return {
|
||||
stageCoordinates,
|
||||
stageDimensions,
|
||||
stageScale,
|
||||
maskColorString: rgbaColorToString(maskColor),
|
||||
shouldInvertMask,
|
||||
};
|
||||
}
|
||||
);
|
||||
@ -114,8 +120,13 @@ const getColoredSVG = (color: string) => {
|
||||
const IAICanvasMaskCompositer = (props: IAICanvasMaskCompositerProps) => {
|
||||
const { ...rest } = props;
|
||||
|
||||
const { maskColorString, stageCoordinates, stageDimensions, stageScale } =
|
||||
useAppSelector(canvasMaskCompositerSelector);
|
||||
const {
|
||||
maskColorString,
|
||||
stageCoordinates,
|
||||
stageDimensions,
|
||||
stageScale,
|
||||
shouldInvertMask,
|
||||
} = useAppSelector(canvasMaskCompositerSelector);
|
||||
|
||||
const [fillPatternImage, setFillPatternImage] =
|
||||
useState<HTMLImageElement | null>(null);
|
||||
@ -162,7 +173,7 @@ const IAICanvasMaskCompositer = (props: IAICanvasMaskCompositerProps) => {
|
||||
fillPatternRepeat={'repeat'}
|
||||
fillPatternScale={{ x: 1 / stageScale, y: 1 / stageScale }}
|
||||
listening={true}
|
||||
globalCompositeOperation={'source-in'}
|
||||
globalCompositeOperation={shouldInvertMask ? 'source-out' : 'source-in'}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
|
@ -546,25 +546,38 @@ export const canvasSlice = createSlice({
|
||||
});
|
||||
},
|
||||
addLine: (state, action: PayloadAction<number[]>) => {
|
||||
const { tool, layer, brushColor, brushSize, eraserSize } =
|
||||
state[state.currentCanvas];
|
||||
const currentCanvas = state[state.currentCanvas];
|
||||
|
||||
const { tool, layer, brushColor, brushSize, eraserSize } = currentCanvas;
|
||||
|
||||
if (tool === 'move') return;
|
||||
|
||||
state[state.currentCanvas].pastObjects.push(
|
||||
state[state.currentCanvas].objects
|
||||
);
|
||||
let newTool: CanvasDrawingTool;
|
||||
|
||||
state[state.currentCanvas].objects.push({
|
||||
if (layer === 'mask' && currentCanvas.shouldInvertMask) {
|
||||
newTool = tool === 'eraser' ? 'brush' : 'eraser';
|
||||
} else {
|
||||
newTool = tool;
|
||||
}
|
||||
|
||||
const newStrokeWidth = tool === 'brush' ? brushSize / 2 : eraserSize / 2;
|
||||
|
||||
// set & then spread this to only conditionally add the "color" key
|
||||
const newColor =
|
||||
layer === 'base' && tool === 'brush' ? { color: brushColor } : {};
|
||||
|
||||
currentCanvas.pastObjects.push(currentCanvas.objects);
|
||||
|
||||
currentCanvas.objects.push({
|
||||
kind: 'line',
|
||||
layer,
|
||||
tool,
|
||||
strokeWidth: tool === 'brush' ? brushSize / 2 : eraserSize / 2,
|
||||
tool: newTool,
|
||||
strokeWidth: newStrokeWidth,
|
||||
points: action.payload,
|
||||
...(layer === 'base' && tool === 'brush' && { color: brushColor }),
|
||||
...newColor,
|
||||
});
|
||||
|
||||
state[state.currentCanvas].futureObjects = [];
|
||||
currentCanvas.futureObjects = [];
|
||||
},
|
||||
addPointToCurrentLine: (state, action: PayloadAction<number[]>) => {
|
||||
const lastLine =
|
||||
@ -579,14 +592,18 @@ export const canvasSlice = createSlice({
|
||||
|
||||
const newObjects = state[state.currentCanvas].pastObjects.pop();
|
||||
if (!newObjects) return;
|
||||
state[state.currentCanvas].futureObjects.unshift(state[state.currentCanvas].objects);
|
||||
state[state.currentCanvas].futureObjects.unshift(
|
||||
state[state.currentCanvas].objects
|
||||
);
|
||||
state[state.currentCanvas].objects = newObjects;
|
||||
},
|
||||
redo: (state) => {
|
||||
if (state[state.currentCanvas].futureObjects.length === 0) return;
|
||||
const newObjects = state[state.currentCanvas].futureObjects.shift();
|
||||
if (!newObjects) return;
|
||||
state[state.currentCanvas].pastObjects.push(state[state.currentCanvas].objects);
|
||||
state[state.currentCanvas].pastObjects.push(
|
||||
state[state.currentCanvas].objects
|
||||
);
|
||||
state[state.currentCanvas].objects = newObjects;
|
||||
},
|
||||
setShouldShowGrid: (state, action: PayloadAction<boolean>) => {
|
||||
|
Loading…
Reference in New Issue
Block a user