make preDefined pad and panel colors

This commit is contained in:
malkuthro
2025-10-18 21:40:40 +02:00
parent b2266115e3
commit 7de0ffecd3
2 changed files with 69 additions and 15 deletions
+33 -15
View File
@@ -11,15 +11,17 @@ class EasyResize:
"base_on": (["Width", "Height"], {"default": "Width"}),
"base_size": ("INT", {"default": 512, "min": 1, "max": MAX_RESOLUTION, "step": 1}),
"aspect_ratio": ("STRING", {"default": "16:9"}),
"divisible_by": ("INT", {"default": 32, "min": 1, "max": 128, "step": 1}),
"upscale_method": (["nearest-exact", "bilinear", "area", "bicubic", "lanczos"], {"default": "nearest-exact"}),
"keep_proportion": (["stretch", "letterbox", "pillarbox"], {"default": "stretch"}),
"pad_color": ("STRING", {"default": "0, 0, 0"}),
"crop_position": (["top", "bottom", "left", "right", "center"], {"default": "center"}),
"divisible_by": ("INT", {"default": 32, "min": 1, "max": 128, "step": 1}),
"pad_color_mode": (["White", "Black", "Gray", "Custom"], {"default": "Black"}),
"panel_color_mode": (["White", "Black", "Gray", "Custom"], {"default": "Black"}),
"device": (["cpu", "cuda"], {"default": "cpu"}),
},
"optional": {
"mask": ("MASK",),
"pad_color": ("STRING", {"default": "0, 0, 0"}),
"panel_color": ("STRING", {"default": "0, 0, 0"}),
}
}
@@ -33,10 +35,11 @@ Adjusts the input image to a target resolution based on a base dimension (width
an aspect ratio (e.g., '16:9' for landscape, '9:16' for portrait), ensuring both dimensions
are divisible by the specified value. Supports stretch or pad/crop modes for proportion control.
Outputs the resized image, optional mask, and final width/height for VFX pipeline integration.
Also outputs a solid color panel (canvas) of the target size using the specified panel_color.
Also outputs a solid color panel (canvas) of the target size using the specified panel_color_mode and optional custom panel_color.
When selecting 'Custom' for pad_color_mode or panel_color_mode, enter the color in the corresponding field as comma-separated floats, e.g., '0.5, 0.5, 0.5' for gray.
"""
def adjust_to_aspect(self, image, base_on, base_size, aspect_ratio, upscale_method, keep_proportion, pad_color, crop_position, divisible_by, device, mask=None, panel_color="0, 0, 0"):
def adjust_to_aspect(self, image, base_on, base_size, aspect_ratio, upscale_method, keep_proportion, pad_color_mode, crop_position, divisible_by, device, panel_color_mode, mask=None, pad_color="0, 0, 0", panel_color="0, 0, 0"):
def round_to_nearest_multiple(number, multiple):
return multiple * round(number / multiple)
@@ -78,6 +81,31 @@ Also outputs a solid color panel (canvas) of the target size using the specified
has_alpha = (C == 4)
# Color map for modes
color_map = {
"White": [1.0, 1.0, 1.0],
"Black": [0.0, 0.0, 0.0],
"Gray": [0.5, 0.5, 0.5],
}
# Determine pad_color_list
if pad_color_mode == "Custom":
pad_color_list = [float(x.strip()) for x in pad_color.split(',')]
else:
pad_color_list = color_map.get(pad_color_mode, [0.0, 0.0, 0.0]) # Default to black if invalid
if len(pad_color_list) != 3:
raise ValueError("Pad color must be three comma-separated floats, e.g., '0, 0, 0'.")
# Determine panel_color_list
if panel_color_mode == "Custom":
panel_color_list = [float(x.strip()) for x in panel_color.split(',')]
else:
panel_color_list = color_map.get(panel_color_mode, [0.0, 0.0, 0.0]) # Default to black if invalid
if len(panel_color_list) != 3:
raise ValueError("Panel color must be three comma-separated floats, e.g., '0, 0, 0'.")
if keep_proportion == "stretch":
# Simple resize
out_image = common_upscale(image, target_width, target_height, upscale_method, "disabled")
@@ -116,15 +144,10 @@ Also outputs a solid color panel (canvas) of the target size using the specified
pad_l = total_pad_w // 2
pad_r = total_pad_w - pad_l
# Parse pad_color
pad_color = [float(x.strip()) for x in pad_color.split(',')]
if len(pad_color) != 3:
raise ValueError("Pad color must be three comma-separated floats, e.g., '0, 0, 0'.")
# Create background with pad color (RGB or RGBA)
pad_channels = 4 if has_alpha else 3
pad_color_tensor = torch.zeros((1, pad_channels, 1, 1), dtype=image.dtype, device=device)
pad_color_tensor[0, :3, 0, 0] = torch.tensor(pad_color, dtype=image.dtype, device=device)
pad_color_tensor[0, :3, 0, 0] = torch.tensor(pad_color_list, dtype=image.dtype, device=device)
if has_alpha:
# Default alpha to 1 (opaque) for padding
pad_color_tensor[0, 3, 0, 0] = 1.0
@@ -142,11 +165,6 @@ Also outputs a solid color panel (canvas) of the target size using the specified
out_mask = out_mask.movedim(1, -1).squeeze(-1) # Squeeze last dim (channel=1) -> [B, H', W']
# Create color panel
# Parse panel_color
panel_color_list = [float(x.strip()) for x in panel_color.split(',')]
if len(panel_color_list) != 3:
raise ValueError("Panel color must be three comma-separated floats, e.g., '0, 0, 0'.")
# Create panel tensor (B=1, C=3, H=target_height, W=target_width)
panel_channels = 3 # RGB, no alpha
color_panel = torch.zeros((1, panel_channels, target_height, target_width), dtype=image.dtype, device=device)
+36
View File
@@ -47,5 +47,41 @@ app.registerExtension({
}, { serialize: false });
};
}
},
async nodeCreated(node) {
if (node.comfyClass !== "EasyResize") return;
// Function to update widgets for a mode
const updateWidgets = (modeName, colorName, value) => {
const colorWidgetIndex = node.widgets.findIndex(w => w.name === colorName);
if (value === "Custom") {
if (colorWidgetIndex === -1) {
node.addWidget("string", colorName, "0, 0, 0", null, { multiline: false });
}
} else {
if (colorWidgetIndex !== -1) {
node.widgets.splice(colorWidgetIndex, 1); // Remove
}
}
node.setDirtyCanvas(true, true);
};
// Pad color mode
const padModeWidget = node.widgets.find(w => w.name === "pad_color_mode");
const origPadCallback = padModeWidget.callback;
padModeWidget.callback = (value) => {
if (origPadCallback) origPadCallback.call(this, value);
updateWidgets("pad_color_mode", "pad_color", value);
};
updateWidgets("pad_color_mode", "pad_color", padModeWidget.value);
// Panel color mode
const panelModeWidget = node.widgets.find(w => w.name === "panel_color_mode");
const origPanelCallback = panelModeWidget.callback;
panelModeWidget.callback = (value) => {
if (origPanelCallback) origPanelCallback.call(this, value);
updateWidgets("panel_color_mode", "panel_color", value);
};
updateWidgets("panel_color_mode", "panel_color", panelModeWidget.value);
}
});