feat(nodes)(ui): Add line mode to ImageAlphaToOutline

Allows the user to pick where the outlines are drawn .. both inside and outside of the alpha region
This commit is contained in:
blessedcoolant
2024-10-27 10:36:45 +05:30
parent 50bda4c889
commit 2a3d819113
5 changed files with 59 additions and 3 deletions

View File

@@ -1070,6 +1070,7 @@ class ImageAlphaToOutlineInvocation(BaseInvocation, WithMetadata, WithBoard):
le=100,
description="The width of the outline as a percentage of image dimension",
)
line_mode: Literal["inner", "outer", "both"] = InputField(default="both", description="Where to apply the mask")
def invoke(self, context: InvocationContext) -> ImageOutput:
img_pil = context.images.get_pil(self.image.image_name, mode="RGBA")
@@ -1097,6 +1098,15 @@ class ImageAlphaToOutlineInvocation(BaseInvocation, WithMetadata, WithBoard):
thickness=line_width,
)
# Limit drawing the outline
if self.line_mode == "inner":
contour_mask = numpy.minimum(contour_mask, binary_mask)
if self.line_mode == "outer":
inverted_binary_mask = cv2.bitwise_not(binary_mask)
contour_mask = cv2.bitwise_and(contour_mask, inverted_binary_mask)
if self.line_mode == "both":
pass
# Create our result image, fully transparent
result_rgba = numpy.zeros((contour_mask.shape[0], contour_mask.shape[1], 4), dtype=numpy.uint8)

View File

@@ -1815,7 +1815,11 @@
"alpha_to_outline": {
"label": "Alpha to Outline",
"description": "Outlines the opaque regions of the image with a line of the given width.",
"line_width_percent": "Line Width Percent"
"line_width_percent": "Line Width Percent",
"line_mode": "Line Mode",
"inner": "Inner",
"outer": "Outer",
"both": "Both"
},
"color_map": {
"label": "Color Map",

View File

@@ -1,4 +1,13 @@
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
import {
CompositeNumberInput,
CompositeSlider,
Flex,
FormControl,
FormLabel,
Radio,
RadioGroup,
Text,
} from '@invoke-ai/ui-library';
import type { AlphaToOutlineFilterConfig } from 'features/controlLayers/store/filters';
import { IMAGE_FILTERS } from 'features/controlLayers/store/filters';
import { useCallback } from 'react';
@@ -18,6 +27,13 @@ export const FilterAlphaToOutline = ({ onChange, config }: Props) => {
[onChange, config]
);
const handleLineModeChange = useCallback(
(v: string) => {
onChange({ ...config, line_mode: v });
},
[onChange, config]
);
return (
<>
<FormControl>
@@ -37,6 +53,22 @@ export const FilterAlphaToOutline = ({ onChange, config }: Props) => {
max={100}
/>
</FormControl>
<FormControl w="min-content">
<FormLabel m={0}>{t('controlLayers.filter.alpha_to_outline.line_mode')}</FormLabel>
<RadioGroup value={config.line_mode} onChange={handleLineModeChange} w="full" size="md">
<Flex alignItems="center" w="full" gap={4} fontWeight="semibold" color="base.300">
<Radio value="both">
<Text>{t('controlLayers.filter.alpha_to_outline.both')}</Text>
</Radio>
<Radio value="inner">
<Text>{t('controlLayers.filter.alpha_to_outline.inner')}</Text>
</Radio>
<Radio value="outer">
<Text>{t('controlLayers.filter.alpha_to_outline.outer')}</Text>
</Radio>
</Flex>
</RadioGroup>
</FormControl>
</>
);
};

View File

@@ -98,6 +98,7 @@ export type SpandrelFilterConfig = z.infer<typeof zSpandrelFilterConfig>;
const zAlphaToOutlineFilterConfig = z.object({
type: z.literal('alpha_to_outline'),
line_width_percent: z.number().gte(1).lte(100),
line_mode: z.string(),
});
export type AlphaToOutlineFilterConfig = z.infer<typeof zAlphaToOutlineFilterConfig>;
@@ -176,14 +177,16 @@ export const IMAGE_FILTERS: { [key in FilterConfig['type']]: ImageFilterData<key
buildDefaults: () => ({
type: 'alpha_to_outline',
line_width_percent: 5,
line_mode: 'both',
}),
buildGraph: ({ image_name }, { line_width_percent }) => {
buildGraph: ({ image_name }, { line_width_percent, line_mode }) => {
const graph = new Graph(getPrefixedId('alpha_to_outline_filter'));
const node = graph.addNode({
id: getPrefixedId('alpha_to_outline'),
type: 'img_alpha_to_outline',
image: { image_name },
line_width_percent,
line_mode,
});
return {
graph,

View File

@@ -7911,6 +7911,13 @@ export type components = {
* @default 5
*/
line_width_percent?: number;
/**
* Line Mode
* @description Where to apply the mask
* @default both
* @enum {string}
*/
line_mode?: "inner" | "outer" | "both";
/**
* type
* @default img_alpha_to_outline