diff --git a/README.md b/README.md index f05c7d3..584ed7e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# πŸ”— Comfyui : Bjornulf_custom_nodes v0.4 πŸ”— +# πŸ”— Comfyui : Bjornulf_custom_nodes v0.5 πŸ”— # Dependencies @@ -6,10 +6,12 @@ # πŸ“ Changelog -- **v0.2 Ollama**: Improve ollama node with system prompt + model selection. -- **v0.3 Save Image to Folder**: Add a new node : Save image to a chosen folder. -- **v0.3 Save Images**: Add comfyui Metadata / workflow to all my image-related nodes. -- **v0.4 Images to video**: Support transparency option with webm format, options encoders. As well as input for audio stream. +- **v0.2**: Improve ollama node with system prompt + model selection. +- **v0.3**: Add a new node : Save image to a chosen folder. +- **v0.3**: Add comfyui Metadata / workflow to all my image-related nodes. +- **v0.4**: Support transparency option with webm format, options encoders. As well as input for audio stream. +- **v0.5**: New node : Remove image transparency (alpha) - Fill alpha channel with solid color. +- **v0.5**: New node : Image to grayscale (black & white) - Convert an image to grayscale. # πŸ“ Nodes descriptions @@ -138,5 +140,21 @@ Create a ping-pong effect from a list of images (from a video) by reversing the **Description:** Combine a sequence of images into a video file. -❓ I made this node because it supports transparency with webm format. (Needed for rembg) -Temporary images are stored in the folder `ComfyUI/temp_images_imgs2video/` as well as the wav audio file. \ No newline at end of file +❓ I made this node because it supports transparency with webm format. (Needed for rembg) +Temporary images are stored in the folder `ComfyUI/temp_images_imgs2video/` as well as the wav audio file. + +## 22 - πŸ”² Remove image Transparency (alpha) +![Images to Video](screenshots/remove_alpha.png) + +**Description:** +Remove transparency from an image by filling the alpha channel with a solid color. (black, white or greenscreen) +Of course it takes in an image with transparency, liek from rembg nodes. +Necessary for some nodes that don't support transparency. + +## 23 - πŸ”² Image to grayscale (black & white) +![Images to Video](screenshots/grayscale.png) + +**Description:** +Convert an image to grayscale (black & white) +Example : I sometimes use it with Ipadapter to disable color influence. +But you can sometimes also want a black and white image... \ No newline at end of file diff --git a/__init__.py b/__init__.py index 2b5c5a8..da26285 100644 --- a/__init__.py +++ b/__init__.py @@ -25,6 +25,8 @@ from .save_api_image import SaveApiImage from .save_img_to_folder import SaveImageToFolder from .resize_image import ResizeImage from .loop_my_combos_samplers_schedulers import LoopCombosSamplersSchedulers +from .remove_transparency import RemoveTransparency +from .image_to_grayscale import GrayscaleTransform # from .CUSTOM_STRING import CustomStringType @@ -32,6 +34,8 @@ NODE_CLASS_MAPPINGS = { # "Bjornulf_CustomStringType": CustomStringType, "Bjornulf_ollamaLoader": ollamaLoader, "Bjornulf_WriteText": WriteText, + "Bjornulf_RemoveTransparency": RemoveTransparency, + "Bjornulf_GrayscaleTransform": GrayscaleTransform, # "Bjornulf_WriteImageEnvironment": WriteImageEnvironment, # "Bjornulf_WriteImageCharacters": WriteImageCharacters, # "Bjornulf_WriteImageCharacter": WriteImageCharacter, @@ -65,6 +69,8 @@ NODE_DISPLAY_NAME_MAPPINGS = { "Bjornulf_ShowText": "πŸ‘ Show (Text)", "Bjornulf_ShowInt": "πŸ‘ Show (Int)", "Bjornulf_ShowFloat": "πŸ‘ Show (Float)", + "Bjornulf_GrayscaleTransform": "πŸ”² Image to grayscale (black & white)", + "Bjornulf_RemoveTransparency": "πŸ”² Remove image Transparency (alpha)", "Bjornulf_ResizeImage": "πŸ“ Resize Image", "Bjornulf_SaveImagePath": "πŸ–Ό Save Image (exact path, exact name) βš οΈπŸ’£", "Bjornulf_SaveImageToFolder": "πŸ–ΌπŸ“ Save Image to a folder", diff --git a/image_to_grayscale.py b/image_to_grayscale.py new file mode 100644 index 0000000..4f736e8 --- /dev/null +++ b/image_to_grayscale.py @@ -0,0 +1,39 @@ +import torch + +class GrayscaleTransform: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "image": ("IMAGE",), + "preserve_alpha": ("BOOLEAN", {"default": False}), + }, + } + + RETURN_TYPES = ("IMAGE",) + FUNCTION = "transform_to_grayscale" + + CATEGORY = "Bjornulf" + + def transform_to_grayscale(self, image, preserve_alpha): + # Check if the image has an alpha channel + has_alpha = image.shape[3] == 4 + + # Extract RGB channels + rgb = image[:, :, :, :3] + + # Convert to grayscale using the luminosity method + # Weights are based on human perception of color + grayscale = 0.2989 * rgb[:,:,:,0] + 0.5870 * rgb[:,:,:,1] + 0.1140 * rgb[:,:,:,2] + + # Expand dimensions to match original shape + grayscale = grayscale.unsqueeze(-1).repeat(1, 1, 1, 3) + + if has_alpha and preserve_alpha: + # If the original image had an alpha channel and we want to preserve it + alpha = image[:, :, :, 3:4] + result = torch.cat([grayscale, alpha], dim=3) + else: + result = grayscale + + return (result,) \ No newline at end of file diff --git a/remove_transparency.py b/remove_transparency.py new file mode 100644 index 0000000..de0f27a --- /dev/null +++ b/remove_transparency.py @@ -0,0 +1,47 @@ +import torch + +class RemoveTransparency: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "image": ("IMAGE",), + "recover_background": ("BOOLEAN", {"default": False}), + "background_color": (["black", "white", "greenscreen"], {"default": "black"}), + }, + } + + RETURN_TYPES = ("IMAGE",) + FUNCTION = "process_transparency" + + CATEGORY = "Bjornulf" + + def process_transparency(self, image, recover_background, background_color): + # Check if the image has an alpha channel + if image.shape[3] == 4: + rgb = image[:, :, :, :3] + alpha = image[:, :, :, 3:4] + + if recover_background: + result = rgb + else: + # Create background color tensor + if background_color == "white": + bg_color = torch.ones_like(rgb) + elif background_color == "greenscreen": + bg_color = torch.zeros_like(rgb) + bg_color[:, :, :, 1] = 1 # Set green channel to 1 + else: # black + bg_color = torch.zeros_like(rgb) + + # Blend the image with the background color + result = rgb * alpha + bg_color * (1 - alpha) + else: + # If there's no alpha channel, return the original image + result = image + + # Ensure the output is always 3 channels (RGB) + if result.shape[3] == 4: + result = result[:, :, :, :3] + + return (result,) \ No newline at end of file diff --git a/screenshots/grayscale.png b/screenshots/grayscale.png new file mode 100644 index 0000000..6a9e815 Binary files /dev/null and b/screenshots/grayscale.png differ diff --git a/screenshots/remove_alpha.png b/screenshots/remove_alpha.png new file mode 100644 index 0000000..3b4def5 Binary files /dev/null and b/screenshots/remove_alpha.png differ