|
import torch |
|
import numpy as np |
|
from PIL import Image |
|
|
|
class ConstrainImageforVideo: |
|
""" |
|
A node that constrains an image to a maximum and minimum size while maintaining aspect ratio. |
|
""" |
|
|
|
@classmethod |
|
def INPUT_TYPES(cls): |
|
return { |
|
"required": { |
|
"images": ("IMAGE",), |
|
"max_width": ("INT", {"default": 1024, "min": 0}), |
|
"max_height": ("INT", {"default": 1024, "min": 0}), |
|
"min_width": ("INT", {"default": 0, "min": 0}), |
|
"min_height": ("INT", {"default": 0, "min": 0}), |
|
"crop_if_required": (["yes", "no"], {"default": "no"}), |
|
}, |
|
} |
|
|
|
RETURN_TYPES = ("IMAGE",) |
|
RETURN_NAMES = ("IMAGE",) |
|
FUNCTION = "constrain_image_for_video" |
|
CATEGORY = "image" |
|
|
|
def constrain_image_for_video(self, images, max_width, max_height, min_width, min_height, crop_if_required): |
|
crop_if_required = crop_if_required == "yes" |
|
results = [] |
|
for image in images: |
|
i = 255. * image.cpu().numpy() |
|
img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8)).convert("RGB") |
|
|
|
current_width, current_height = img.size |
|
aspect_ratio = current_width / current_height |
|
|
|
constrained_width = max(min(current_width, min_width), max_width) |
|
constrained_height = max(min(current_height, min_height), max_height) |
|
|
|
if constrained_width / constrained_height > aspect_ratio: |
|
constrained_width = max(int(constrained_height * aspect_ratio), min_width) |
|
if crop_if_required: |
|
constrained_height = int(current_height / (current_width / constrained_width)) |
|
else: |
|
constrained_height = max(int(constrained_width / aspect_ratio), min_height) |
|
if crop_if_required: |
|
constrained_width = int(current_width / (current_height / constrained_height)) |
|
|
|
resized_image = img.resize((constrained_width, constrained_height), Image.LANCZOS) |
|
|
|
if crop_if_required and (constrained_width > max_width or constrained_height > max_height): |
|
left = max((constrained_width - max_width) // 2, 0) |
|
top = max((constrained_height - max_height) // 2, 0) |
|
right = min(constrained_width, max_width) + left |
|
bottom = min(constrained_height, max_height) + top |
|
resized_image = resized_image.crop((left, top, right, bottom)) |
|
|
|
resized_image = np.array(resized_image).astype(np.float32) / 255.0 |
|
resized_image = torch.from_numpy(resized_image)[None,] |
|
results.append(resized_image) |
|
all_images = torch.cat(results, dim=0) |
|
|
|
return (all_images, all_images.size(0),) |
|
|
|
NODE_CLASS_MAPPINGS = { |
|
"ConstrainImageforVideo|pysssss": ConstrainImageforVideo, |
|
} |
|
|
|
NODE_DISPLAY_NAME_MAPPINGS = { |
|
"ConstrainImageforVideo|pysssss": "Constrain Image for Video ๐", |
|
} |
|
|