remove test file

This commit is contained in:
jammyfu
2025-01-27 14:06:33 +08:00
parent 0ab0e0666c
commit 5cd5276ecd
4 changed files with 0 additions and 352 deletions
-26
View File
@@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
# Filename: click_popup.py
# Developer: jammyfu
# Category: 🎨Painting👓Coder/🔧Utils
class ClickPopup:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"button": ("BOOLEAN", {"default": False}),
},
}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("message",)
FUNCTION = "show_popup"
CATEGORY = "🎨Painting👓Coder/🔧Utils"
def show_popup(self, button):
return ("Button clicked!",)
# 添加到 ComfyUI 节点注册
NODE_CLASS_MAPPINGS = {
"ClickPopup": ClickPopup,
}
-44
View File
@@ -1,44 +0,0 @@
import torch
import numpy as np
from PIL import Image
class ColorPicker:
"""
颜色选择器节点,使用 jscolor 实现颜色选择和吸管工具
"""
def __init__(self):
self.color = "#000000"
@classmethod
def INPUT_TYPES(s):
return {"required": {}} # 不需要输入项
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("color",)
FUNCTION = "pick_color"
CATEGORY = "🎨Painting👓Coder/🎨Color"
def pick_color(self):
return (self.color,)
@classmethod
def VALIDATE_INPUTS(s, **kwargs):
return True
def widget_value_updated(self, widget, value):
if widget.name == "color_picker":
self.color = value
@classmethod
def WIDGETS(s):
return {"color_picker": ("color", {"default": "#000000"})}
# 在 __init__.py 中添加节点注册
NODE_CLASS_MAPPINGS = {
"ColorPicker": ColorPicker
}
NODE_DISPLAY_NAME_MAPPINGS = {
"ColorPicker": "Color Picker"
}
-190
View File
@@ -1,190 +0,0 @@
# -*- coding: utf-8 -*-
# Filename: image_scale_calculator.py
# Developer: jammyfu
# Category: 🎨Painting👓Coder/🖼️Image
import torch
import numpy as np
from PIL import Image
def resize_image(image, target_width, target_height, method='contain'):
"""Resize an image while maintaining aspect ratio.
method: 'contain' (保持宽高比,缩放图像以完全适应容器),
'cover' (保持宽高比,缩放图像以覆盖整个容器),
'fill' (忽略宽高比,缩放图像以完全填充容器),
'inside' (保持宽高比,缩小或不改变图像使其完全适合容器),
'outside' (保持宽高比,放大或不改变图像使其完全覆盖容器).
"""
# 将ComfyUI的图像Tensor转换为PIL图像对象
img = Image.fromarray(np.clip(255. * image.cpu().numpy(), 0, 255).astype(np.uint8))
img_width, img_height = img.size
if method == 'contain':
# Contain: 缩放图像以适应目标尺寸,保持宽高比,可能出现黑边
img_ratio = img_width / img_height
target_ratio = target_width / target_height
if img_ratio > target_ratio:
new_width = target_width
new_height = int(target_width / img_ratio)
else:
new_height = target_height
new_width = int(target_height * img_ratio)
resized_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
padded_img = Image.new('RGB', (target_width, target_height), 'black') # 创建黑色背景
x_offset = (target_width - new_width) // 2
y_offset = (target_height - new_height) // 2
padded_img.paste(resized_img, (x_offset, y_offset)) # 将缩放后的图片贴到中心
return np.array(padded_img).astype(np.float32)/255.0, new_width, new_height
elif method == 'cover':
# Cover: 缩放图像以覆盖目标尺寸,保持宽高比,可能裁剪
img_ratio = img_width / img_height
target_ratio = target_width / target_height
if img_ratio > target_ratio:
new_height = target_height
new_width = int(target_height * img_ratio)
else:
new_width = target_width
new_height = int(target_width / img_ratio)
resized_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
x_offset = (new_width - target_width) // 2
y_offset = (new_height - target_height) // 2
cropped_img = resized_img.crop((x_offset, y_offset, x_offset + target_width, y_offset + target_height)) # 裁剪中心部分
return np.array(cropped_img).astype(np.float32)/255.0 , target_width, target_height
elif method == 'fill':
# Fill: 拉伸图像以填充目标尺寸,忽略宽高比,可能变形
resized_img = img.resize((target_width, target_height), Image.Resampling.LANCZOS)
return np.array(resized_img).astype(np.float32)/255.0, target_width, target_height
elif method == 'inside':
# Inside: 和 contain 相同,保持宽高比,缩小或不改变图像使其完全适合容器
img_ratio = img_width / img_height
target_ratio = target_width / target_height
if img_ratio > target_ratio:
new_width = target_width
new_height = int(target_width / img_ratio)
else:
new_height = target_height
new_width = int(target_height * img_ratio)
resized_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
padded_img = Image.new('RGB', (target_width, target_height), 'black')
x_offset = (target_width - new_width) // 2
y_offset = (target_height - new_height) // 2
padded_img.paste(resized_img, (x_offset, y_offset))
return np.array(padded_img).astype(np.float32)/255.0, new_width, new_height
elif method == 'outside':
# Outside: 和 cover 相同,保持宽高比,放大或不改变图像使其完全覆盖容器
img_ratio = img_width / img_height
target_ratio = target_width / target_height
if img_ratio > target_ratio:
new_height = target_height
new_width = int(target_height * img_ratio)
else:
new_width = target_width
new_height = int(target_width / img_ratio)
resized_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
x_offset = (new_width - target_width) // 2
y_offset = (new_height - target_height) // 2
cropped_img = resized_img.crop((x_offset, y_offset, x_offset + target_width, y_offset + target_height))
return np.array(cropped_img).astype(np.float32)/255.0 , target_width, target_height
def crop_image(image, target_width, target_height, position='center'):
"""Crop an image to the target dimensions.
position: 'center' (居中),
'top-left' (左上角),
'top-right' (右上角),
'bottom-left' (左下角),
'bottom-right' (右下角).
"""
img = Image.fromarray(np.clip(255. * image.cpu().numpy(), 0, 255).astype(np.uint8))
img_width, img_height = img.size
if img_width < target_width or img_height < target_height:
raise ValueError(f"image size is less than target size, current width={img_width}, height={img_height}, target_width={target_width}, target_height={target_height}")
if position == 'center':
x_offset = (img_width - target_width) // 2
y_offset = (img_height - target_height) // 2
elif position == 'top-left':
x_offset = 0
y_offset = 0
elif position == 'top-right':
x_offset = img_width - target_width
y_offset = 0
elif position == 'bottom-left':
x_offset = 0
y_offset = img_height - target_height
elif position == 'bottom-right':
x_offset = img_width - target_width
y_offset = img_height - target_height
else:
raise ValueError(f"Invalid crop position: {position}")
cropped_img = img.crop((x_offset, y_offset, x_offset + target_width, y_offset + target_height))
return np.array(cropped_img).astype(np.float32) / 255.0, target_width, target_height
class ImageScaleCalculator:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"image": ("IMAGE",), # Input image
"scale_type": (["ratio", "max_width", "max_height", "force_size", "crop"],), # Scale type
"scale_ratio": ("FLOAT", {"default": 1.0, "min": 0.01, "max": 100.0, "step": 0.01}), # Scale ratio
"max_width": ("INT", {"default": 512, "min": 1, "max": 8192, "step": 1}), # Max width
"max_height": ("INT", {"default": 512, "min": 1, "max": 8192, "step": 1}), # Max height
"target_width": ("INT", {"default": 512, "min": 1, "max": 8192, "step": 1}), # Target width
"target_height": ("INT", {"default": 512, "min": 1, "max": 8192, "step": 1}), # Target height
"crop_position": (["center", "top-left", "top-right", "bottom-left", "bottom-right"],), # Crop position
"method": (["contain", "cover", "fill", "inside", "outside"],), # Resize method
}
}
RETURN_TYPES = ("IMAGE", "INT", "INT")
RETURN_NAMES = ("image", "width", "height")
FUNCTION = "scale_image"
CATEGORY = "🎨Painting👓Coder/🖼️Image" # Node category
def scale_image(self, image, scale_type, scale_ratio, max_width, max_height, target_width, target_height, crop_position, method):
img = image[0] # Get the image
img_width = img.shape[1]
img_height = img.shape[0]
if scale_type == "ratio":
target_width = int(img_width * scale_ratio)
target_height = int(img_height * scale_ratio)
# 应用最大尺寸限制
target_width = min(target_width, max_width)
target_height = min(target_height, max_height)
scaled_image, width, height = resize_image(img, target_width, target_height, method=method) # Scale by ratio with limits
elif scale_type == "max_width":
target_width = max_width
target_height = int(img_height * (max_width / img_width))
# 应用最大尺寸限制
target_height = min(target_height, max_height)
scaled_image, width, height = resize_image(img, target_width, target_height, method="contain") # Scale by max width with limits
elif scale_type == "max_height":
target_height = max_height
target_width = int(img_width * (max_height / img_height))
# 应用最大尺寸限制
target_width = min(target_width, max_width)
scaled_image, width, height = resize_image(img, target_width, target_height, method="contain") # Scale by max height with limits
elif scale_type == "force_size":
scaled_image, width, height = resize_image(img, target_width, target_height, method="fill") # Force target width and height
elif scale_type == "crop":
scaled_image, width, height = crop_image(img, target_width, target_height, crop_position) # Crop image
return (torch.from_numpy(scaled_image).unsqueeze(0), width, height)
@@ -1,92 +0,0 @@
# 创建者: jammyfu
import re
class RemoveEmptyLinesAndLeadingSpacesAdvance:
"""
一个 ComfyUI 自定义节点,用于移除文本中多余的空行和行首空格。
"""
@classmethod
def INPUT_TYPES(s):
"""
定义节点的输入类型。
Returns:
dict: 包含 'required' 和 'optional' 输入定义的字典。
"""
return {
"required": {
"text": ("STRING", {"multiline": True}),
"output_type": (["String", "List"], {"default": "String"}),
},
"optional": {
"remove_empty_lines_option": ("BOOLEAN", {"default": True}),
"remove_leading_spaces_option": ("BOOLEAN", {"default": True}),
"preview": ("BOOLEAN", {"default": False}),
"output_preview": ("STRING", {"multiline": True, "readonly": True, "default": "", "display": "none"})
}
}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("output",)
OUTPUT_NODE = True
FUNCTION = "process_text"
CATEGORY = "🎨Painting👓Coder/📝Text"
# 定义 OUTPUT_IS_LIST
OUTPUT_IS_LIST = [False]
@classmethod
def IS_CHANGED(s, **kwargs):
preview = kwargs.get("preview", False)
if preview:
return float("nan")
return False
def process_text(self, text, output_type, remove_empty_lines_option, remove_leading_spaces_option, preview, output_preview):
"""
处理文本的函数,根据按钮值移除空行和行首空格。
Args:
text (str): 输入的文本字符串。
output_type (str): 输出类型,"String" 或 "List"。
remove_empty_lines_option (bool): 是否移除空行的标志。
remove_leading_spaces_option (bool): 是否移除行首空格的标志。
preview (bool): 是否显示预览窗口。
output_preview (str): 输出预览文本。
Returns:
tuple: 包含处理后的文本(字符串或字符串列表)和预览UI。
"""
processed_text = text
if remove_empty_lines_option or remove_leading_spaces_option:
lines = processed_text.split('\n')
if remove_leading_spaces_option:
lines = [line.strip() for line in lines]
if remove_empty_lines_option:
lines = [line for line in lines if line.strip()]
result = lines if output_type == "List" else "\n".join(lines)
else:
result = text.splitlines() if output_type == "List" else text
if preview:
return {
"ui": {
"output_preview": [result, {"multiline": True, "readonly": True, "height": 300}]
},
"result": (result,)
}
else:
return (result,)
# 节点类映射,用于 ComfyUI 注册
NODE_CLASS_MAPPINGS = {
"RemoveEmptyLinesAndLeadingSpacesAdvance": RemoveEmptyLinesAndLeadingSpacesAdvance
}
# 节点显示名称映射,用于 ComfyUI 显示
NODE_DISPLAY_NAME_MAPPINGS = {
"RemoveEmptyLinesAndLeadingSpacesAdv": "Remove Empty Lines & Leading Spaces Advance"
}