From d71e4db764e6f4a985ede39984b01da90518fda2 Mon Sep 17 00:00:00 2001 From: "Alexander G. Morano" Date: Thu, 6 Mar 2025 15:25:58 -0500 Subject: [PATCH] auto-size masks during mask add fix some limits on transform node fix inversion in pixel merge --- core/calc.py | 6 +++--- core/compose.py | 25 +++++++++++++------------ sup/image/__init__.py | 2 ++ sup/image/adjust.py | 2 ++ web/widget/widget_vector.js | 11 +++++------ 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/core/calc.py b/core/calc.py index 3b2fa5e..59435af 100644 --- a/core/calc.py +++ b/core/calc.py @@ -274,7 +274,7 @@ Perform single function operations like absolute value, mean, median, mode, magn d = super().INPUT_TYPES() d = deep_merge(d, { "optional": { - Lexicon.IN_A: (JOV_TYPE_FULL, {"default": None}), + Lexicon.IN_A: (JOV_TYPE_NUMERICAL, {"default": None}), Lexicon.FUNC: (EnumUnaryOperation._member_names_, {"default": EnumUnaryOperation.ABS.name}) } }) @@ -377,9 +377,9 @@ Execute binary operations like addition, subtraction, multiplication, division, d = super().INPUT_TYPES() d = deep_merge(d, { "optional": { - Lexicon.IN_A: (JOV_TYPE_FULL, {"default": None, + Lexicon.IN_A: (JOV_TYPE_NUMERICAL, {"default": None, "tooltip":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}), - Lexicon.IN_B: (JOV_TYPE_FULL, {"default": None, + Lexicon.IN_B: (JOV_TYPE_NUMERICAL, {"default": None, "tooltip":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}), Lexicon.FUNC: (EnumBinaryOperation._member_names_, {"default": EnumBinaryOperation.ADD.name, "tooltip":"Arithmetic operation to perform"}), Lexicon.TYPE: (names_convert, {"default": names_convert[2], diff --git a/core/compose.py b/core/compose.py index eab9ba8..c1aa73c 100644 --- a/core/compose.py +++ b/core/compose.py @@ -786,13 +786,14 @@ Combines individual color channels (red, green, blue) along with an optional mas _, _, w_max, h_max = image_minmax(img) for i, x in enumerate(img): - img[i] = x if x is None: - img[i] = np.full((h_max, w_max), matte[i], dtype=np.uint8) + x = np.full((h_max, w_max), matte[i], dtype=np.uint8) if flip[i] > 0: - img[i] = image_invert(x, flip[i]) + x = image_invert(x, flip[i]) + img[i] = x img = channel_merge(img) + img = image_invert(img, 1) if mode != EnumScaleMode.MATTE: w, h = wihi @@ -1008,16 +1009,16 @@ Apply various geometric transformations to images, including translation, rotati "optional": { Lexicon.PIXEL: (JOV_TYPE_IMAGE, {}), Lexicon.MASK: (JOV_TYPE_IMAGE, {}), - Lexicon.XY: ("VEC2", {"default": (0, 0,), "mij": -1, "maj": 1, "step": 0.01, "label": [Lexicon.X, Lexicon.Y]}), - Lexicon.ANGLE: ("FLOAT", {"default": 0, "step": 0.01}), + Lexicon.XY: ("VEC2", {"default": (0., 0.,), "mij": -1., "maj": 1., "step": 0.01, "label": [Lexicon.X, Lexicon.Y]}), + Lexicon.ANGLE: ("FLOAT", {"default": 0., "step": 0.1}), Lexicon.SIZE: ("VEC2", {"default": (1., 1.), "mij": 0.001, "step": 0.01, "label": [Lexicon.X, Lexicon.Y]}), - Lexicon.TILE: ("VEC2", {"default": (1., 1.), "mij": 1, "step": 0.01, "label": [Lexicon.X, Lexicon.Y]}), + Lexicon.TILE: ("VEC2", {"default": (1., 1.), "mij": 1., "step": 0.01, "label": [Lexicon.X, Lexicon.Y]}), Lexicon.EDGE: (EnumEdge._member_names_, {"default": EnumEdge.CLIP.name}), Lexicon.MIRROR: (EnumMirrorMode._member_names_, {"default": EnumMirrorMode.NONE.name}), Lexicon.PIVOT: ("VEC2", {"default": (0.5, 0.5), "step": 0.005, "label": [Lexicon.X, Lexicon.Y]}), Lexicon.PROJECTION: (EnumProjection._member_names_, {"default": EnumProjection.NORMAL.name}), - Lexicon.TLTR: ("VEC4", {"default": (0, 0, 1, 0), "step": 0.005, "label": [Lexicon.TOP, Lexicon.LEFT, Lexicon.TOP, Lexicon.RIGHT]}), - Lexicon.BLBR: ("VEC4", {"default": (0, 1, 1, 1), "step": 0.005, "label": [Lexicon.BOTTOM, Lexicon.LEFT, Lexicon.BOTTOM, Lexicon.RIGHT]}), + Lexicon.TLTR: ("VEC4", {"default": (0., 0., 1., 0.), "mij": 0., "maj": 1., "step": 0.005, "label": [Lexicon.TOP, Lexicon.LEFT, Lexicon.TOP, Lexicon.RIGHT]}), + Lexicon.BLBR: ("VEC4", {"default": (0., 1., 1., 1.), "mij": 0., "maj": 1., "step": 0.005, "label": [Lexicon.BOTTOM, Lexicon.LEFT, Lexicon.BOTTOM, Lexicon.RIGHT]}), Lexicon.STRENGTH: ("FLOAT", {"default": 1, "min": 0, "step": 0.005}), Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.MATTE.name}), Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), @@ -1030,16 +1031,16 @@ Apply various geometric transformations to images, including translation, rotati def run(self, **kw) -> Tuple[torch.Tensor, ...]: pA = parse_param(kw, Lexicon.PIXEL, EnumConvertType.IMAGE, None) mask = parse_param(kw, Lexicon.MASK, EnumConvertType.IMAGE, None) - offset = parse_param(kw, Lexicon.XY, EnumConvertType.VEC2, [(0, 0)], -2.5, 2.5) + offset = parse_param(kw, Lexicon.XY, EnumConvertType.VEC2, [(0., 0.)], -2.5, 2.5) angle = parse_param(kw, Lexicon.ANGLE, EnumConvertType.FLOAT, 0) - size = parse_param(kw, Lexicon.SIZE, EnumConvertType.VEC2, [(1, 1)], 0.001) + size = parse_param(kw, Lexicon.SIZE, EnumConvertType.VEC2, [(1., 1.)], 0.001) edge = parse_param(kw, Lexicon.EDGE, EnumEdge, EnumEdge.CLIP.name) mirror = parse_param(kw, Lexicon.MIRROR, EnumMirrorMode, EnumMirrorMode.NONE.name) mirror_pivot = parse_param(kw, Lexicon.PIVOT, EnumConvertType.VEC2, [(0.5, 0.5)], 0, 1) tile_xy = parse_param(kw, Lexicon.TILE, EnumConvertType.VEC2, [(1., 1.)], 1) proj = parse_param(kw, Lexicon.PROJECTION, EnumProjection, EnumProjection.NORMAL.name) - tltr = parse_param(kw, Lexicon.TLTR, EnumConvertType.VEC4, [(0, 0, 1, 0)], 0, 1) - blbr = parse_param(kw, Lexicon.BLBR, EnumConvertType.VEC4, [(0, 1, 1, 1)], 0, 1) + tltr = parse_param(kw, Lexicon.TLTR, EnumConvertType.VEC4, [(0., 0., 1., 0.)], 0, 1) + blbr = parse_param(kw, Lexicon.BLBR, EnumConvertType.VEC4, [(0., 1., 1., 1.)], 0, 1) strength = parse_param(kw, Lexicon.STRENGTH, EnumConvertType.FLOAT, 1, 0, 1) mode = parse_param(kw, Lexicon.MODE, EnumScaleMode, EnumScaleMode.MATTE.name) wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, [(512, 512)], MIN_IMAGE_SIZE) diff --git a/sup/image/__init__.py b/sup/image/__init__.py index 1e3e66a..687f000 100644 --- a/sup/image/__init__.py +++ b/sup/image/__init__.py @@ -216,6 +216,8 @@ def image_mask_add(image:TYPE_IMAGE, mask:TYPE_IMAGE=None, alpha:float=255) -> T """ image = image_convert(image, 4) mask = image_mask(image, alpha) if mask is None else image_convert(mask, 1) + h, w, c = image.shape + mask = cv2.resize(mask, (w, h)) image[..., 3] = mask if mask.ndim == 2 else mask[:, :, 0] return image diff --git a/sup/image/adjust.py b/sup/image/adjust.py index 5cf1b8b..27dc4b2 100644 --- a/sup/image/adjust.py +++ b/sup/image/adjust.py @@ -472,6 +472,8 @@ def image_translate(image: TYPE_IMAGE, offset: TYPE_fCOORD2D=(0.0, 0.0), height, width = img.shape[:2] scalarX = 0.333 if edge in [EnumEdge.WRAP, EnumEdge.WRAPX] else 1.0 scalarY = 0.333 if edge in [EnumEdge.WRAP, EnumEdge.WRAPY] else 1.0 + scalarX = 1.0 + scalarY = 1.0 M = np.float32([[1, 0, offset[0] * width * scalarX], [0, 1, offset[1] * height * scalarY]]) if edge == EnumEdge.CLIP: diff --git a/web/widget/widget_vector.js b/web/widget/widget_vector.js index dcd6670..350ab7a 100644 --- a/web/widget/widget_vector.js +++ b/web/widget/widget_vector.js @@ -1,6 +1,4 @@ -/** - * File: widget_vector.js - */ +/**/ import { app } from "../../../scripts/app.js" import { $el } from "../../../scripts/ui.js" @@ -164,8 +162,9 @@ const VectorWidget = (app, inputName, options, initial, desc='') => { pointer.onClick = (eUp) => { /* if click on header, reset to defaults */ - if (index == -1) { - widget.value = Object.assign({}, widget.options.default); + if (index == -1 && eUp.shiftKey) { + widget.value = Object.assign([], widget.options.default); + return; } else if (index >= 0 && index < size) { const pos = [eUp.canvasX - node.pos[0], eUp.canvasY - node.pos[1]] @@ -200,7 +199,7 @@ const VectorWidget = (app, inputName, options, initial, desc='') => { } if (!this.options?.rgb) return; - const rgba = Object.values(this?.value || []); + const rgba = widget.value; const color = colorRGB2Hex(rgba.slice(0, 3)); if (index != size && (x < 0 && rgba.length > 2)) {