LayerColor: AutoAdjust¶
Documentation¶
- Class name:
LayerColor: AutoAdjust
- Category:
😺dzNodes/LayerColor
- Output node:
False
The AutoAdjust node provides automated adjustments to the color properties of an image, including brightness, contrast, saturation, and individual color channels. It aims to enhance the image's overall appearance or correct its color balance based on specified parameters.
Input types¶
Required¶
image
- The input image to be adjusted. This parameter is crucial as it serves as the base for all subsequent color corrections and enhancements.
- Comfy dtype:
IMAGE
- Python dtype:
Image
strength
- Determines the intensity of the automatic adjustments applied to the image, affecting the overall impact of the correction.
- Comfy dtype:
INT
- Python dtype:
int
brightness
- Adjusts the brightness level of the image, influencing its lightness or darkness.
- Comfy dtype:
INT
- Python dtype:
int
contrast
- Modifies the contrast of the image, enhancing or reducing the difference between its light and dark areas.
- Comfy dtype:
INT
- Python dtype:
int
saturation
- Alters the saturation level, adjusting the intensity of the image's colors.
- Comfy dtype:
INT
- Python dtype:
int
red
- Adjusts the red color channel, allowing for fine-tuning of the image's red hues.
- Comfy dtype:
INT
- Python dtype:
int
green
- Adjusts the green color channel, enabling modifications to the image's green tones.
- Comfy dtype:
INT
- Python dtype:
int
blue
- Adjusts the blue color channel, facilitating adjustments to the blue hues in the image.
- Comfy dtype:
INT
- Python dtype:
int
Optional¶
Output types¶
image
- Comfy dtype:
IMAGE
- The output image after applying the auto adjustments, reflecting changes in color properties such as brightness, contrast, saturation, and color channels.
- Python dtype:
Image
- Comfy dtype:
Usage tips¶
- Infra type:
CPU
- Common nodes: unknown
Source code¶
class AutoAdjust:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(self):
return {
"required": {
"image": ("IMAGE", ), #
"strength": ("INT", {"default": 100, "min": 0, "max": 100, "step": 1}),
"brightness": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}),
"contrast": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}),
"saturation": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}),
"red": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}),
"green": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}),
"blue": ("INT", {"default": 0, "min": -100, "max": 100, "step": 1}),
},
"optional": {
}
}
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = 'auto_adjust'
CATEGORY = '😺dzNodes/LayerColor'
def auto_adjust(self, image, strength, brightness, contrast, saturation, red, green, blue):
if brightness < 0:
brightness_offset = brightness / 100 + 1
else:
brightness_offset = brightness / 50 + 1
if contrast < 0:
contrast_offset = contrast / 100 + 1
else:
contrast_offset = contrast / 50 + 1
if saturation < 0:
saturation_offset = saturation / 100 + 1
else:
saturation_offset = saturation / 50 + 1
red_gamma = self.balance_to_gamma(red)
green_gamma = self.balance_to_gamma(green)
blue_gamma = self.balance_to_gamma(blue)
l_images = []
l_masks = []
ret_images = []
for l in image:
l_images.append(torch.unsqueeze(l, 0))
m = tensor2pil(l)
if m.mode == 'RGBA':
l_masks.append(m.split()[-1])
else:
l_masks.append(Image.new('L', m.size, 'white'))
max_batch = max(len(l_images), len(l_masks))
for i in range(max_batch):
_image = l_images[i] if i < len(l_images) else l_images[-1]
_mask = l_masks[i] if i < len(l_masks) else l_masks[-1]
orig_image = tensor2pil(_image)
r, g, b, _ = image_channel_split(orig_image, mode = 'RGB')
r = normalize_gray(r)
g = normalize_gray(g)
b = normalize_gray(b)
if red:
r = gamma_trans(r, red_gamma).convert('L')
if green:
g = gamma_trans(g, green_gamma).convert('L')
if blue:
b = gamma_trans(b, blue_gamma).convert('L')
ret_image = image_channel_merge((r, g, b), 'RGB')
if brightness:
brightness_image = ImageEnhance.Brightness(ret_image)
ret_image = brightness_image.enhance(factor=brightness_offset)
if contrast:
contrast_image = ImageEnhance.Contrast(ret_image)
ret_image = contrast_image.enhance(factor=contrast_offset)
if saturation:
color_image = ImageEnhance.Color(ret_image)
ret_image = color_image.enhance(factor=saturation_offset)
ret_image = chop_image_v2(orig_image, ret_image, blend_mode="normal", opacity=strength)
if orig_image.mode == 'RGBA':
ret_image = RGB2RGBA(ret_image, orig_image.split()[-1])
ret_images.append(pil2tensor(ret_image))
log(f"{NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish')
return (torch.cat(ret_images, dim=0),)
def balance_to_gamma(self, balance:int) -> float:
return 0.00005 * balance * balance - 0.01 * balance + 1