diff --git a/README.MD b/README.MD
index efc1350..8ee76b5 100644
--- a/README.MD
+++ b/README.MD
@@ -70,6 +70,7 @@ When this error has occurred, please check the network environment.
## Update
**If the dependency package error after updating, please reinstall the relevant dependency packages.
+* Commit [AutoAdjust](#AutoAdjust) node, it can automatically adjust image contrast and white balance.
* Commit [RGBValue](#RGBValue) node to output the color value as a single decimal value of R, G, B. This idea is from [vxinhao](https://github.com/vxinhao/color2rgb), Thanks.
* Commit [seed](#seed) node to output the seed value. The [ImageMaskScaleAs](#ImageMaskScaleAs), [ImageScaleBySspectRatio](#ImageScaleBySspectRatio), [ImageScaleBySspectRatioV2](#ImageScaleBySspectRatioV2), [ImageScaleRestore](#ImageScaleRestore), [ImageScaleRestoreV2](#ImageScaleRestoreV2) nodes increase ```width```, ```height``` output.
* Commit [Levels](#Levels) node, it can achieve the same color levels adjustment function as Photoshop.[Sharp&Soft](#Sharp) add the "None" option.
@@ -323,6 +324,20 @@ Node options:
Open the text editing software and find the line starting with "LUT_dir=", after "=", enter the custom folder path name. all .cube files in this folder will be collected and displayed in the node list during ComfyUI initialization.
If the folder set in ini is invalid, the LUT folder that comes with the plugin will be enabled.
+### AutoAdjust
+Automatically adjust the brightness, contrast, and white balance of the image. Provide some manual adjustment options to compensate for the shortcomings of automatic adjustment.
+
+
+Node Options:
+
+* strength: Strength of adjust. The larger the value, the greater the difference from the original image.
+* brightness: Manual adjustment of brightness.
+* contrast: Manual adjustment of contrast.
+* saturation: Manual adjustment of saturation.
+* red: Manual adjustment of the red channel.
+* green: Manual adjustment of the green channel.
+* blue: Manual adjustment of the blue channel.
+
### AutoBrightness
Automatically adjust too dark or too bright image to moderate brightness, and support mask input. When mask input, only the content of the mask part is used as the data source of the automatic brightness. The output is still the whole adjusted image.

diff --git a/README_CN.MD b/README_CN.MD
index c3bb066..c8aaeaa 100644
--- a/README_CN.MD
+++ b/README_CN.MD
@@ -70,6 +70,7 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git
## 更新说明
**如果本插件更新后出现依赖包错误,请重新安装相关依赖包。
+* 添加 [AutoAdjust](#AutoAdjust) 节点, 自动调整图片对比度和白平衡。
* 添加 [RGBValue](#RGBValue) 节点, 将色值输出为单独的R, G, B三个10进制数值。这个想法来自[vxinhao](https://github.com/vxinhao/color2rgb),感谢。
* 添加[seed](#seed) 节点,输出种子值。[ImageMaskScaleAs](#ImageMaskScaleAs), [ImageScaleBySspectRatio](#ImageScaleBySspectRatio), [ImageScaleBySspectRatioV2](#ImageScaleBySspectRatioV2), [ImageScaleRestore](#ImageScaleRestore), [ImageScaleRestoreV2](#ImageScaleRestoreV2) 节点增加```width```, ```height``` 输出。
* 添加 [Levels](#Levels) 节点, 可以实现与Photoshop相同的色阶调整功能。[Sharp&Soft](#Sharp)增加"None"选项。
@@ -129,7 +130,6 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git
* 添加 [ChannelShake](#ChannelShake)节点,这是一个滤镜,能产生类似抖音logo的通道错位效果。
* 添加 [MaskGradient](#MaskGradient)节点,可使mask产生渐变。
* 添加 [GetColorTone](#GetColorTone)节点,可以获取图片的主色或平均色。添加[MaskGrow](#MaskGrow)和[MaskEdgeShrink](#MaskEdgeShrink)节点。
-
* 添加 [MaskBoxDetect](#MaskBoxDetect)节点,可以通过mask自动探测位置并输出到合成节点。添加[XY to Percent](#Percent)节点,将绝对坐标转换为percent坐标。添加[GaussianBlur](#GaussianBlur)节点。添加[GetImageSize](#GetImageSize)节点。
* 添加 [ExtendCanvas](#ExtendCanvas)节点。
* 添加 [ImageBlendAdvance](#ImageBlendAdvance)节点。这个节点允许合成尺寸不同的背景图和图层,提供了更加自由的合成体验。
@@ -318,6 +318,20 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git
*LUT文件夹在```resource_dir.ini```中定义,这个文件位于插件根目录下, 默认名字是```resource_dir.ini.example```, 初次使用这个文件需将文件后缀改为.ini。用文本编辑软件打开,找到“LUT_dir=”开头的这一行,编辑“=”之后为自定义文件夹路径名。这个文件夹里面所有的.cube文件将在ComfyUI初始化时被收集并显示在节点的列表中。如果ini中设定的文件夹无效,将启用插件自带的LUT文件夹。
+### AutoAdjust
+自动调整图片的亮度,对比度和白平衡。提供一些手动调整选项以弥补自动调整的不足。
+
+
+节点选项说明:
+
+* strength: 调整的强度。数值越大,与原图的差别越大。
+* brightness: 亮度手动调整。
+* contrast: 对比度手动调整。
+* saturation: 色彩饱和度手动调整。
+* red: 红色通道手动调整。
+* green: 绿色通道手动调整。
+* blue: 蓝色通道手动调整。
+
### AutoBrightness
将过暗或过亮的图片自动调整到适中的亮度,支持遮罩输入。有遮罩输入时仅以遮罩部分的内容作为自动亮度的数据来源。输出仍然是整个调整后的图像。

diff --git a/image/auto_adjust_example.png b/image/auto_adjust_example.png
new file mode 100644
index 0000000..806803d
Binary files /dev/null and b/image/auto_adjust_example.png differ
diff --git a/image/auto_adjust_node.png b/image/auto_adjust_node.png
new file mode 100644
index 0000000..0b44bfb
Binary files /dev/null and b/image/auto_adjust_node.png differ
diff --git a/py/blendmodes.py b/py/blendmodes.py
index 6db0994..cf2ae25 100644
--- a/py/blendmodes.py
+++ b/py/blendmodes.py
@@ -1,6 +1,6 @@
"""
-@author: Chris Freilich
-@description: This extension provides a blend modes node with 30 blend modes.
+author: Chris Freilich
+description: This extension provides a blend modes node with 30 blend modes.
"""
from PIL import Image
import numpy as np
diff --git a/py/color_correct_auto_adjust.py b/py/color_correct_auto_adjust.py
new file mode 100644
index 0000000..b7e4d7d
--- /dev/null
+++ b/py/color_correct_auto_adjust.py
@@ -0,0 +1,111 @@
+from .imagefunc import *
+
+NODE_NAME = 'AutoAdjust'
+
+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
+
+NODE_CLASS_MAPPINGS = {
+ "LayerColor: AutoAdjust": AutoAdjust
+}
+
+NODE_DISPLAY_NAME_MAPPINGS = {
+ "LayerColor: AutoAdjust": "LayerColor: AutoAdjust"
+}
\ No newline at end of file
diff --git a/py/imagefunc.py b/py/imagefunc.py
index 1a11b13..13fad82 100644
--- a/py/imagefunc.py
+++ b/py/imagefunc.py
@@ -699,6 +699,19 @@ def draw_rect(image:Image, x:int, y:int, width:int, height:int, line_color:str,
def draw_border(image:Image, border_width:int, color:str='#FFFFFF') -> Image:
return ImageOps.expand(image, border=border_width, fill=color)
+# 对灰度图像进行直方图均衡化
+def normalize_gray(image:Image) -> Image:
+ if image.mode != 'L':
+ image = image.convert('L')
+ img = np.asarray(image)
+ balanced_img = img.copy()
+ hist, bins = np.histogram(img.reshape(-1), 256, (0, 256))
+ bmin = np.min(np.where(hist > (hist.sum() * 0.0005)))
+ bmax = np.max(np.where(hist > (hist.sum() * 0.0005)))
+ balanced_img = np.clip(img, bmin, bmax)
+ balanced_img = ((balanced_img - bmin) / (bmax - bmin) * 255)
+ return Image.fromarray(balanced_img).convert('L')
+
def remap_pixel(pixel:int, min_brightness:int, max_brightness:int) -> int:
return int((pixel - min_brightness) / (max_brightness - min_brightness) * 255)
def histogram_range(image:Image, black_point:int, black_range:int, white_point:int, white_range:int) -> Image:
diff --git a/py/mask_edge_ultrl_detail.py b/py/mask_edge_ultra_detail.py
similarity index 100%
rename from py/mask_edge_ultrl_detail.py
rename to py/mask_edge_ultra_detail.py
diff --git a/py/mask_edge_ultrl_detail_v2.py b/py/mask_edge_ultra_detail_v2.py
similarity index 100%
rename from py/mask_edge_ultrl_detail_v2.py
rename to py/mask_edge_ultra_detail_v2.py
diff --git a/py/shadow&highlight_mask.py b/py/shadow_highlight_mask.py
similarity index 100%
rename from py/shadow&highlight_mask.py
rename to py/shadow_highlight_mask.py
diff --git a/py/sharp&soft.py b/py/sharp_soft.py
similarity index 100%
rename from py/sharp&soft.py
rename to py/sharp_soft.py
diff --git a/py/TextJoin.py b/py/text_join.py
similarity index 100%
rename from py/TextJoin.py
rename to py/text_join.py
diff --git a/py/yolov8_detect.py b/py/yolov8_detect.py
index aad45e4..5812512 100644
--- a/py/yolov8_detect.py
+++ b/py/yolov8_detect.py
@@ -1,3 +1,4 @@
+
import copy
import os.path