mirror of
https://github.com/justUmen/Bjornulf_custom_nodes.git
synced 2026-03-21 12:42:11 -03:00
new node : cut image from mask
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# 🔗 Comfyui : Bjornulf_custom_nodes v0.13 🔗
|
||||
# 🔗 Comfyui : Bjornulf_custom_nodes v0.14 🔗
|
||||
|
||||
# Dependencies
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
- **v0.11**: Add a new node : Text with random Seed - Generate a random seed, along with text.
|
||||
- **v0.12**: Combine images : Add option to move vertically and horizontally. (from -50% to 150%)
|
||||
- **v0.13**: Add a new node: Load image with transparency (alpha) - Load an image with transparency.
|
||||
- **v0.14**: Add a new node: Cut image from a mask
|
||||
|
||||
# 📝 Nodes descriptions
|
||||
|
||||
@@ -234,3 +235,9 @@ FLUX : Here is an example of 4 images without Random Seed node on the left, and
|
||||
**Description:**
|
||||
Load an image with transparency.
|
||||
The default `Load Image` node will not load the transparency.
|
||||
|
||||
## 30 - 🖼✂ Cut image with a mask
|
||||

|
||||
|
||||
**Description:**
|
||||
Cut an image from a mask.
|
||||
@@ -34,6 +34,7 @@ from .random_line_from_input import RandomLineFromInput
|
||||
from .loop_lines import LoopAllLines
|
||||
from .random_seed_with_text import TextToStringAndSeed
|
||||
from .load_image_alpha import LoadImageWithTransparency
|
||||
from .image_mask_cutter import ImageMaskCutter
|
||||
# from .check_black_image import CheckBlackImage
|
||||
# from .clear_vram import ClearVRAM
|
||||
|
||||
@@ -42,6 +43,7 @@ from .load_image_alpha import LoadImageWithTransparency
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
# "Bjornulf_CustomStringType": CustomStringType,
|
||||
"Bjornulf_ollamaLoader": ollamaLoader,
|
||||
"Bjornulf_ImageMaskCutter": ImageMaskCutter,
|
||||
"Bjornulf_LoadImageWithTransparency": LoadImageWithTransparency,
|
||||
"Bjornulf_LoopAllLines": LoopAllLines,
|
||||
"Bjornulf_TextToStringAndSeed": TextToStringAndSeed,
|
||||
@@ -84,6 +86,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
# "Bjornulf_CustomStringType": "!!! CUSTOM STRING TYPE !!!",
|
||||
"Bjornulf_ollamaLoader": "🦙 Ollama (Description)",
|
||||
"Bjornulf_ImageMaskCutter": "🖼✂ Cut Image with Mask",
|
||||
"Bjornulf_LoadImageWithTransparency": "🖼 Load Image with Transparency ▢",
|
||||
"Bjornulf_GreenScreenToTransparency": "🟩➜▢ Green Screen to Transparency",
|
||||
# "Bjornulf_CheckBlackImage": "🔲 Check Black Image (Empty mask)",
|
||||
|
||||
@@ -8,7 +8,8 @@ class CombineBackgroundOverlay:
|
||||
return {
|
||||
"required": {
|
||||
"background": ("IMAGE",),
|
||||
"overlay_alpha": ("IMAGE",),
|
||||
"overlay": ("IMAGE",),
|
||||
"mask": ("MASK",),
|
||||
"horizontal_position": ("FLOAT", {"default": 50, "min": -50, "max": 150, "step": 0.1}),
|
||||
"vertical_position": ("FLOAT", {"default": 50, "min": -50, "max": 150, "step": 0.1}),
|
||||
},
|
||||
@@ -18,7 +19,7 @@ class CombineBackgroundOverlay:
|
||||
FUNCTION = "combine_background_overlay"
|
||||
CATEGORY = "Bjornulf"
|
||||
|
||||
def combine_background_overlay(self, background, overlay_alpha, horizontal_position, vertical_position):
|
||||
def combine_background_overlay(self, background, overlay, mask, horizontal_position, vertical_position):
|
||||
# Convert background from torch tensor to numpy array
|
||||
bg = background[0].numpy()
|
||||
bg = (bg * 255).astype(np.uint8)
|
||||
@@ -26,17 +27,23 @@ class CombineBackgroundOverlay:
|
||||
|
||||
results = []
|
||||
|
||||
for overlay in overlay_alpha:
|
||||
for ov, m in zip(overlay, mask):
|
||||
# Convert overlay from torch tensor to numpy array
|
||||
ov = overlay.numpy()
|
||||
ov = ov.numpy()
|
||||
ov = (ov * 255).astype(np.uint8)
|
||||
|
||||
# Convert mask from torch tensor to numpy array
|
||||
m = m.numpy()
|
||||
m = (m * 255).astype(np.uint8)
|
||||
|
||||
# Create PIL Image for overlay
|
||||
if ov.shape[2] == 4:
|
||||
ov_img = Image.fromarray(ov, 'RGBA')
|
||||
else:
|
||||
ov_img = Image.fromarray(ov, 'RGB')
|
||||
ov_img = ov_img.convert('RGBA')
|
||||
|
||||
# Create alpha channel from mask
|
||||
alpha = Image.fromarray(m, 'L')
|
||||
|
||||
# Combine RGB overlay with alpha mask
|
||||
ov_img.putalpha(alpha)
|
||||
|
||||
# Calculate horizontal position
|
||||
x = int((horizontal_position / 100) * (bg_img.width - ov_img.width))
|
||||
@@ -56,8 +63,7 @@ class CombineBackgroundOverlay:
|
||||
# Convert back to numpy array and then to torch tensor
|
||||
result_np = np.array(result)
|
||||
|
||||
# If the result is RGBA, convert to RGB
|
||||
if result_np.shape[2] == 4:
|
||||
# Convert RGBA to RGB
|
||||
result_np = result_np[:,:,:3]
|
||||
|
||||
result_tensor = torch.from_numpy(result_np).float() / 255.0
|
||||
|
||||
46
image_mask_cutter.py
Normal file
46
image_mask_cutter.py
Normal file
@@ -0,0 +1,46 @@
|
||||
import torch
|
||||
|
||||
class ImageMaskCutter:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"image": ("IMAGE",),
|
||||
"mask": ("MASK",),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
FUNCTION = "cut_image"
|
||||
|
||||
CATEGORY = "Bjornulf"
|
||||
|
||||
def cut_image(self, image, mask):
|
||||
print(f"Image shape: {image.shape}")
|
||||
print(f"Mask shape: {mask.shape}")
|
||||
|
||||
# Check if image channels are in the last dimension
|
||||
if image.shape[-1] == 3 or image.shape[-1] == 4:
|
||||
# Move channels to second dimension
|
||||
image = image.permute(0, 3, 1, 2)
|
||||
|
||||
# Ensure image and mask have compatible dimensions
|
||||
if image.shape[2:] != mask.shape[1:]:
|
||||
raise ValueError(f"Image and mask must have compatible dimensions. Got image shape {image.shape} and mask shape {mask.shape}")
|
||||
|
||||
# Convert mask to float and ensure it's in the range [0, 1]
|
||||
mask = mask.float()
|
||||
mask = torch.clamp(mask, 0, 1)
|
||||
|
||||
# If image is RGB, convert to RGBA
|
||||
if image.shape[1] == 3:
|
||||
alpha = torch.ones((image.shape[0], 1, image.shape[2], image.shape[3]), device=image.device)
|
||||
image = torch.cat([image, alpha], dim=1)
|
||||
|
||||
# Use the mask as the alpha channel
|
||||
image[:, 3:4, :, :] = mask.unsqueeze(1)
|
||||
|
||||
# Move channels back to the last dimension
|
||||
cut_image = image.permute(0, 2, 3, 1)
|
||||
|
||||
return (cut_image,)
|
||||
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "bjornulf_custom_nodes"
|
||||
description = "Nodes: Ollama, Green Screen to Transparency, Save image for Bjornulf LobeChat, Text with random Seed, Random line from input, Combine images (Background+Overlay alpha), Image to grayscale (black & white), Remove image Transparency (alpha), Resize Image, ..."
|
||||
version = "0.13"
|
||||
version = "0.14"
|
||||
license = {file = "LICENSE"}
|
||||
|
||||
[project.urls]
|
||||
|
||||
BIN
screenshots/image_mask_cut.png
Normal file
BIN
screenshots/image_mask_cut.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 305 KiB |
Reference in New Issue
Block a user