Create Morph Image from Path
Crossfade a folder of images into a GIF/APNG
- filepath_text
- filename_text
This one does exactly what it says, and it's worth being upfront about what it isn't: it's not an AI interpolation node like RIFE, FILM, or AMT-VFI that computes motion between frames and generates the in-betweens. Create Morph Image from Path is a straight crossfade - it takes a folder of images and fades between them in sequence, writing the result out as a GIF or APNG. Simple, cheap, and it looks like exactly what it is: a dissolve transition, not true motion interpolation.
Why you'd reach for it
It's the folder-based sibling of Create Morph Image, which does the same fade but between two image inputs you wire in directly. This version points at a directory instead - useful if you've got a batch of generations you want strung together into a slideshow-with-crossfades, say a LoRA training checkpoint comparison, a style progression, or a set of seed variations you want to flip through smoothly rather than as a hard cut. The README also lists a related Write to Morph GIF node for appending frames to an existing animation incrementally, if you're building the sequence up over time rather than pointing at a folder that's already complete.
What it needs
A path to a directory of images is the core input - per the README it also takes an optional glob pattern, the same style used elsewhere in the suite (things like *.jpg to grab just JPEGs, or **/* to pull in subdirectories too). Point it at a folder, optionally narrow down which files it picks up, and it hands back the finished animation.
Installing it
Through ComfyUI Manager: search "WAS Node Suite", install, restart. Manual install:
cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/was-node-suite-comfyui
cd was-node-suite-comfyui
pip install -r requirements.txt
No extra download for this one specifically - it's pure image processing, no model weights involved. The suite's requirements.txt covers its needs.
Troubleshooting
Ordering matters and it isn't obvious: file globbing typically returns names in whatever order the filesystem or glob library hands them back, which isn't always the order you generated them in. If your morph looks like it's fading between the wrong pairs, check that your source filenames sort correctly (zero-padded frame numbers - 001.png, 002.png - rather than 1.png, 2.png, which sorts 1, 10, 11, 2...) before assuming the node is broken.
Beyond that, the general WAS Node Suite caveat applies here as everywhere in this pack: it's been unmaintained since the author stepped back in December 2023, so if you hit an import failure after updating ComfyUI's core, that's almost always a dependency version conflict in the suite itself rather than anything to do with this specific node - check your console output for the actual import error and, if it points at BLIP or another legacy dependency you don't use, that's the known culprit.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| transition_frames | INT | 302–60 | How many blended frames are drawn between each pair of images. 2 is almost a hard cut, 30 is a smooth fade, and every extra frame adds to the file size. |
| still_image_delay_ms | FLOAT | 2500.00.1–60000 | How long each source image is held before it starts to fade, in milliseconds. 2500 holds it for two and a half seconds. |
| duration_ms | FLOAT | 0.10.1–60000 | How long each blended frame is shown, in milliseconds. The default 0.1 asks for the shortest frame the format allows, which most players round up to about 10ms; raise it to slow the fade down. |
| loops | INT | 00–100 | How many times the animation plays before it stops. 0 means play forever, which is what most viewers expect from a GIF. |
| max_size | INT | 512128–1280 | Longest edge of the animation, in pixels. The canvas is otherwise as large as the largest source, so 512 holds a 4000x3000 photograph down to 512x384 and cuts the file and the memory with it. A source already smaller than this is left alone. |
| input_root | COMBO | Which folder the source images are in: ComfyUI's own 'input', 'output' or 'temp', or any folder added under paths.allow_read in config.yaml, listed by its own name. input_folder names the part below it. | |
| input_folder | STRING | Folder below the input root holding the frames, such as 'plates/shot_01'. Empty reads the root itself. | |
| input_pattern | STRING | * | Which names in that folder to take. '*' takes every image, 'frame_*.png' only the PNGs whose name starts with 'frame_'. Subfolders are not searched, and files that are not images are ignored whatever the pattern says. |
| output_root | COMBO | Which folder the animation lands in: ComfyUI's own 'output' or 'temp', or any folder added under paths.allow_write in config.yaml, listed by its own name. output_folder names the part below it. | |
| output_folder | STRING | Folder below the output root the animation is written to, created if it is not there. Tokens expand, so '[time(%Y-%m-%d)]' files each day's under a dated folder. | |
| filename | STRING | morph | Name of the file, without an extension, the format below adds one. Tokens are expanded here too, so '[time(%H-%M-%S)]_morph' gives every run its own file instead of overwriting the last one. |
| filetype | COMBO | Which format to write. `GIF` plays anywhere but bands gradients at 256 colours; `APNG`, `WEBP` and `WEBP_LOSSLESS` keep full colour and alpha. | |
| palette_mode | COMBO | How the palette is chosen when colours are reduced. `per_frame` fits one per frame, `global` one to the whole animation, so a still area stays put. | |
| max_colors | INT | 2562–256 | How many colours the palette holds. 256 is the most a .gif can carry. Lower values shrink the file and give a flatter, posterised look, and below about 64 the choice of palette_mode starts to show. The full-colour formats ignore this at 256 and honour it below that, so it doubles as a posterise control for them. |
| dither | BOOLEAN | true | Scatter the rounding error between neighbouring pixels so a gradient stays smooth instead of breaking into bands. Turn it off for flat, poster-like colour, which also compresses smaller. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| filepath_text | STRING | Full path of the file that was written, extension included. Empty when the input folder held no images. |
| filename_text | STRING | The filename widget as it was typed, with no folder and no extension. Empty when nothing was written. |