diff --git a/README.MD b/README.MD index 35116a0..6df0f1b 100644 --- a/README.MD +++ b/README.MD @@ -147,6 +147,7 @@ When this error has occurred, please check the network environment. **If the dependency package error after updating, please double clicking ```repair_dependency.bat``` (for Official ComfyUI Protable) or ```repair_dependency_aki.bat``` (for ComfyUI-aki-v1.x) in the plugin folder to reinstall the dependency packages.
+* Commit [PadImageBatch](#PadImageBatch) and [RestorePadImageBatch](#RestorePadImageBatch) nodes, used to expand the batch size of video images. * Commit [ImageBatchToList](#ImageBatchToList) and [ImageListToBatch](#ImageListToBatch) nodes, Used for converting single batches of images into multiple small batches and vice versa, with option to define the maximum number of images in each small batch. * Commit [DistortDisplace](#DistortDisplace) node, Generate displacement deformation effects for material images. * Commit [MaskEdgeUltraDetailV3](#MaskEdgeUltraDetailV3) node, By processing different partitions through inputting a trimap mask, a more refined overall mask including translucent parts is generated. @@ -1849,6 +1850,23 @@ Node Options: Merge multiple small batches of images into one large batch. ![image](image/image_batch_to_list(multi)_node.jpg) +### PadImageBatch +Extend the Image Batch to the number of frames that conform to the specified rule, such as ```8n+1```. + +Node Options: +![image](image/pad_image_batch_node.jpg) +* multiplier: The multiplier for the frame number rule. For example, the "8" in "8n+1" +* remainder: The remainder of the frame number rule. For example, the "1" in "8n+1" +Outputs: +* original_batch_length: Original Frames. + +### RestorePadImageBatch +Restore the Image Batch to its original quantity after expanding the frame count. + +Node Options: +![image](image/restore_pad_image_batch_node.jpg) +* original_batch_length: Original Frames. + # LayerMask diff --git a/README_CN.MD b/README_CN.MD index 62f412b..61a9dba 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -128,6 +128,7 @@ os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com' ## 更新说明 **如果本插件更新后出现依赖包错误,请双击运行插件目录下的```install_requirements.bat```(官方便携包),或 ```install_requirements_aki.bat```(秋叶整合包) 重新安装依赖包。 +* 添加 [PadImageBatch](#PadImageBatch) 和 [RestorePadImageBatch](#RestorePadImageBatch) 节点,用于扩展视频图片批次数量。 * 添加 [ImageBatchToList](#ImageBatchToList) 和 [ImageListToBatch](#ImageListToBatch) 节点, 用于图片单个大批次和多个小批次互相转换,支持定义小批次数量。 * 添加 [DistortDisplace](#DistortDisplace) 节点, 为材质图片生成置换变形效果。 * 添加 [MaskEdgeUltraDetailV3](#MaskEdgeUltraDetailV3) 节点, 通过输入trimap遮罩对不同分区处理,生成包括更加精细半透明部分的整体遮罩。 @@ -1660,6 +1661,24 @@ BooleanOperator的升级版,增加了节点内数值输入,增加了大于 ![image](image/image_batch_to_list(multi)_node.jpg) +### PadImageBatch +扩展Image Batch到符合指定规则的帧数,例如```8n+1```。 + +节点选项说明: +![image](image/pad_image_batch_node.jpg) +* multiplier: 帧数规则的乘数。例如```8n+1```中的```8``` +* remainder: 帧数规则的余数。例如```8n+1```中的```1``` +输出: +* original_batch_length: 原始帧数。 + +### RestorePadImageBatch +把经过扩展帧数处理后的Image Batch恢复到原始数量。 + +节点选项说明: +![image](image/restore_pad_image_batch_node.jpg) +* original_batch_length: 原始帧数。 + + # LayerMask ![image](image/layermask_nodes.jpg) diff --git a/image/pad_image_batch_node.jpg b/image/pad_image_batch_node.jpg new file mode 100644 index 0000000..bc69ff9 Binary files /dev/null and b/image/pad_image_batch_node.jpg differ diff --git a/image/restore_pad_image_batch_node.jpg b/image/restore_pad_image_batch_node.jpg new file mode 100644 index 0000000..3db8d76 Binary files /dev/null and b/image/restore_pad_image_batch_node.jpg differ diff --git a/py/pad_batch.py b/py/pad_batch.py new file mode 100644 index 0000000..2677f1b --- /dev/null +++ b/py/pad_batch.py @@ -0,0 +1,103 @@ +import torch + + +class PadImageBatchTo8NPlus1: + """Pad an IMAGE batch to the smallest length matching multiplier*n+remainder.""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "images": ("IMAGE",), + "multiplier": ( + "INT", + {"default": 8, "min": 1, "max": 999, "step": 1}, + ), + "remainder": ( + "INT", + {"default": 1, "min": 0, "max": 999, "step": 1}, + ), + } + } + + RETURN_TYPES = ("IMAGE", "INT") + RETURN_NAMES = ("images", "original_batch_length") + FUNCTION = "pad_batch" + CATEGORY = '😺dzNodes/LayerUtility' + + def pad_batch( + self, + images: torch.Tensor, + multiplier: int = 8, + remainder: int = 1, + ): + original_length = len(images) + if original_length == 0: + raise ValueError("Cannot pad an empty IMAGE batch.") + if multiplier < 1: + raise ValueError("Multiplier must be at least 1.") + if remainder < 0 or remainder >= multiplier: + raise ValueError( + "Remainder must satisfy 0 <= remainder < multiplier " + f"({remainder} is invalid for multiplier {multiplier})." + ) + + n = max( + 0, + (original_length - remainder + multiplier - 1) // multiplier, + ) + target_length = multiplier * n + remainder + padding_length = target_length - original_length + + if padding_length == 0: + return (images, original_length) + + repeated_last_frame = images[-1:].expand( + padding_length, *images.shape[1:] + ) + padded_images = torch.cat((images, repeated_last_frame), dim=0) + return (padded_images, original_length) + + +class RestoreImageBatchLength: + """Crop a processed IMAGE batch back to its original length.""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "images": ("IMAGE",), + "original_batch_length": ( + "INT", + {"forceInput": True}, + ), + } + } + + RETURN_TYPES = ("IMAGE",) + RETURN_NAMES = ("images",) + FUNCTION = "restore_batch" + CATEGORY = '😺dzNodes/LayerUtility' + + def restore_batch(self, images: torch.Tensor, original_batch_length: int): + current_length = len(images) + if original_batch_length < 1: + raise ValueError("Original batch length must be at least 1.") + if original_batch_length > current_length: + raise ValueError( + "Original batch length cannot exceed the input IMAGE batch length " + f"({original_batch_length} > {current_length})." + ) + + return (images[:original_batch_length],) + + +NODE_CLASS_MAPPINGS = { + "LayerUtility: Pad Image Batch to 8n+1": PadImageBatchTo8NPlus1, + "LayerUtility: Restore Pad Image Batch": RestoreImageBatchLength, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "LayerUtility: PadImageBatch": "LayerUtility: Pad Image Batch to 8n+1", + "LayerUtility: RestorePadImageBatch": "LayerUtility: Restore Pad Image Batch", +} diff --git a/pyproject.toml b/pyproject.toml index a8806da..798b468 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui_layerstyle" description = "A set of nodes for ComfyUI it generate image like Adobe Photoshop's Layer Style. the Drop Shadow is first completed node, and follow-up work is in progress." -version = "2.0.38" +version = "2.0.39" license = {text = "MIT License"} dependencies = ["numpy", "pillow", "torch", "matplotlib", "Scipy", "scikit_image", "scikit_learn", "opencv-contrib-python", "pymatting", "timm", "colour-science", "transformers", "blend_modes", "huggingface_hub", "loguru"]