Skip to content

Commit 1f99bac

Browse files
fix(nodes): expanded masks not 100% transparent outside the fade out region
The polynomial fit isn't perfect and we end up with alpha values of 1 instead of 0 when applying the mask. This in turn causes issues on canvas where outputs aren't 100% transparent and individual layer bbox calculations are incorrect.
1 parent a53e1cc commit 1f99bac

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

invokeai/app/invocations/image.py

+16-3
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
10891089

10901090

10911091
@invocation(
1092-
"expand_mask_with_fade", title="Expand Mask with Fade", tags=["image", "mask"], category="image", version="1.0.0"
1092+
"expand_mask_with_fade", title="Expand Mask with Fade", tags=["image", "mask"], category="image", version="1.0.1"
10931093
)
10941094
class ExpandMaskWithFadeInvocation(BaseInvocation, WithMetadata, WithBoard):
10951095
"""Expands a mask with a fade effect. The mask uses black to indicate areas to keep from the generated image and white for areas to discard.
@@ -1147,8 +1147,21 @@ def invoke(self, context: InvocationContext) -> ImageOutput:
11471147
coeffs = numpy.polyfit(x_control, y_control, 3)
11481148
poly = numpy.poly1d(coeffs)
11491149

1150-
# Evaluate and clip the smooth mapping
1151-
feather = numpy.clip(poly(d_norm), 0, 1)
1150+
# Evaluate the polynomial
1151+
feather = poly(d_norm)
1152+
1153+
# The polynomial fit isn't perfect. Points beyond the fade distance are likely to be slightly less than 1.0,
1154+
# even though the control points indicate that they should be exactly 1.0. This is due to the nature of the
1155+
# polynomial fit, which is a best approximation of the control points but not an exact match.
1156+
1157+
# When this occurs, the area outside the mask and fade-out will not be 100% transparent. For example, it may
1158+
# have an alpha value of 1 instead of 0. So we must force pixels at or beyond the fade distance to exactly 1.0.
1159+
1160+
# Force pixels at or beyond the fade distance to exactly 1.0
1161+
feather = numpy.where(d_norm >= 1.0, 1.0, feather)
1162+
1163+
# Clip any other values to ensure they're in the valid range [0,1]
1164+
feather = numpy.clip(feather, 0, 1)
11521165

11531166
# Build final image.
11541167
np_result = numpy.where(black_mask == 1, 0, (feather * 255).astype(numpy.uint8))

0 commit comments

Comments
 (0)