| """JoyEcho Reference Batch - None-tolerant image batcher for reference images. |
| |
| Combines up to 4 optional IMAGE inputs into one batch for |
| JoyEcho_Generate.reference_image. Unlike generic batch nodes (KJNodes |
| ImageBatchMulti crashes on None), inputs that are missing - e.g. a RefPicker |
| that found no character match and emitted its "no reference" None - are simply |
| skipped. If ALL inputs are missing, outputs None, which Generate treats as |
| "no reference wired": the item renders without identity seeding instead of |
| killing the queue. |
| |
| Mixed sizes are resized (lanczos, center-crop semantics via common_upscale) |
| to the first present image's dimensions; Generate cover-fits every ref frame |
| to the video dimensions afterwards anyway. |
| """ |
|
|
| import torch |
|
|
| import comfy.utils |
|
|
|
|
| class JoyEcho_RefBatch: |
| @classmethod |
| def INPUT_TYPES(cls): |
| return { |
| "required": {}, |
| "optional": { |
| "image_1": ("IMAGE",), |
| "image_2": ("IMAGE",), |
| "image_3": ("IMAGE",), |
| "image_4": ("IMAGE",), |
| }, |
| } |
|
|
| RETURN_TYPES = ("IMAGE",) |
| RETURN_NAMES = ("reference_image",) |
| FUNCTION = "batch" |
| CATEGORY = "JoyAI-Echo" |
|
|
| def batch(self, image_1=None, image_2=None, image_3=None, image_4=None): |
| imgs = [i for i in (image_1, image_2, image_3, image_4) |
| if i is not None and i.shape[0] > 0] |
| if not imgs: |
| print("[JoyEcho] RefBatch: no reference images present; " |
| "passing None (Generate skips identity seeding).", flush=True) |
| return (None,) |
| h, w = imgs[0].shape[1], imgs[0].shape[2] |
| out = [] |
| for img in imgs: |
| if img.shape[1] != h or img.shape[2] != w: |
| img = comfy.utils.common_upscale( |
| img.movedim(-1, 1), w, h, "lanczos", "center").movedim(1, -1) |
| out.append(img) |
| return (torch.cat(out, dim=0),) |
|
|
|
|
| NODE_CLASS_MAPPINGS = {"JoyEcho_RefBatch": JoyEcho_RefBatch} |
| NODE_DISPLAY_NAME_MAPPINGS = {"JoyEcho_RefBatch": "JoyEcho Reference Batch (None-tolerant)"} |
|
|