From d2b9ea0b7a0ceaade97daa1997651ebce0858bb6 Mon Sep 17 00:00:00 2001 From: Premik <842962+Premik@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:56:36 +0100 Subject: [PATCH] Transparency --- image_warper.py | 10 +++++----- img_patch_editor.py | 32 ++++++++++++++++++++++++++++---- nodes.py | 19 ++++++++++++++++++- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/image_warper.py b/image_warper.py index c8df598..8eeffbb 100644 --- a/image_warper.py +++ b/image_warper.py @@ -96,11 +96,11 @@ class ImageWarper: print("RANSAC failed to find a model.") return edited.resize(original.size, Image.Resampling.LANCZOS) - print(f"Matches: {len(matches12)}") - print(f"Inliers: {np.sum(inliers)}") - print(f"Scale: {model_robust.scale:.4f}") - print(f"Rotation: {model_robust.rotation:.4f} rad") - print(f"Translation: {model_robust.translation}") + # print(f"Matches: {len(matches12)}") + # print(f"Inliers: {np.sum(inliers)}") + # print(f"Scale: {model_robust.scale:.4f}") + # print(f"Rotation: {model_robust.rotation:.4f} rad") + # print(f"Translation: {model_robust.translation}") # Warp the edited image edited_arr = np.array(edited.convert('RGBA')) diff --git a/img_patch_editor.py b/img_patch_editor.py index b2b57b5..223f045 100644 --- a/img_patch_editor.py +++ b/img_patch_editor.py @@ -139,6 +139,8 @@ class PatchMerger: min_area_size: int = 4 threshold: int = 10 blur_radius: float = 3.0 + mask_expansion: int = 0 + edit_max_alpha: float = 1.0 @cached_property def raw_mask(self) -> Image.Image: @@ -157,8 +159,24 @@ class PatchMerger: return mask @cached_property - def final_mask(self) -> Image.Image: + def sized_mask(self) -> Image.Image: mask = self.raw_mask + if self.mask_expansion == 0: + return mask + + # The kernel size for a radius of N is 2*N+1 + size = abs(self.mask_expansion) * 2 + 1 + + if self.mask_expansion > 0: + # Expand (Dilation) + return mask.filter(ImageFilter.MaxFilter(size)) + else: + # Shrink (Erosion) + return mask.filter(ImageFilter.MinFilter(size)) + + @cached_property + def final_mask(self) -> Image.Image: + mask = self.sized_mask if self.blur_radius > 0: mask = mask.filter(ImageFilter.GaussianBlur(self.blur_radius)) return mask @@ -167,8 +185,14 @@ class PatchMerger: def merged_image(self) -> Image.Image: img1, img2 = self.detector.images mask = self.final_mask - # Composite img2 onto img1 using mask - return Image.composite(img2, img1, mask) + + if self.edit_max_alpha >= 1.0: + # Composite img2 onto img1 using mask + return Image.composite(img2, img1, mask) + + # Blend original and edited images + blended_img = Image.blend(img1, img2, self.edit_max_alpha) + return Image.composite(blended_img, img1, mask) @cached_property def debug_overlay(self) -> Image.Image: @@ -183,7 +207,7 @@ class PatchMerger: blended = Image.alpha_composite(overlay, highlight) # Composite using mask - return Image.composite(blended, overlay, self.raw_mask) + return Image.composite(blended, overlay, self.sized_mask) @property def base_name(self) -> str: diff --git a/nodes.py b/nodes.py index c5cb572..4d2d6c9 100644 --- a/nodes.py +++ b/nodes.py @@ -29,6 +29,14 @@ class ImgPatchNode: "FLOAT", {"default": 3.0, "min": 0.0, "max": 100.0, "step": 0.1, "tooltip": "Radius of the gaussian blur applied to the mask."}, ), + "mask_expansion": ( + "INT", + {"default": 0, "min": -128, "max": 128, "tooltip": "Expand or shrink the mask. Positive values expand, negative values shrink."}, + ), + "edit_max_alpha": ( + "FLOAT", + {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01, "tooltip": "Maximum alpha for the edited image overlay."}, + ), "allow_rescale": ("BOOLEAN", {"default": False, "tooltip": "If true, rescales the edited image to match original size."}), }, } @@ -55,6 +63,8 @@ class ImgPatchNode: min_area_size: int, threshold: int, blur_radius: float, + mask_expansion: int, + edit_max_alpha: float, allow_rescale: bool, ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]: @@ -85,7 +95,14 @@ class ImgPatchNode: allow_rescale=allow_rescale, detection_alg=detection_alg, ) - merger = PatchMerger(detector=detector, min_area_size=min_area_size, threshold=threshold, blur_radius=blur_radius) + merger = PatchMerger( + detector=detector, + min_area_size=min_area_size, + threshold=threshold, + blur_radius=blur_radius, + mask_expansion=mask_expansion, + edit_max_alpha=edit_max_alpha, + ) out_merged.append(self._pil_to_tensor(merger.merged_image)) out_final_masks.append(self._mask_to_tensor(merger.final_mask))