AOI_Processing_Zho
One still image that secretly holds an entire animation
- images
- image
- mask
If you've ever scrolled past one of those posts where a photo seems to wink, spin, or wave as it moves across your screen, you've seen what this node does. AOI_Processing_Zho takes a batch of animation frames and fuses them into a single image that plays the whole animation back when you slide a striped mask over it - the classic slit-scan / lenticular trick, wrapped up as one ComfyUI node. No model, no weights, no GPU work. It's a small, oddly charming utility from ZHO-ZHO-ZHO, the same author behind ComfyUI-PuLID-ZHO and dozens of other wrapper packs.
What it actually does
You feed it images, a batch of frames (say 8 or 16), and it slices every frame into thin vertical strips, then interleaves them into one frame: strip 0 of frame 0, strip 0 of frame 1, strip 0 of frame 2, then strip 1 of frame 0, and so on. Because each group of strips is laid out in frame order, a mask that reveals exactly one strip per group shows frame 0 - slide that mask one strip-width sideways and it shows frame 1. Keep sliding and you get a full animation living inside a static picture. That's the whole illusion.
It also hands you the mask that does the revealing: an RGBA overlay with the first frame's strips transparent and everything else black, so you don't have to build the striping yourself. Wire image and mask into a compositing setup (or a MaskToImage → alpha merge) and you've got the "animated optical illusion" effect, ready to animate with whatever mask movement your display method supports - scroll position, a sliding overlay, an AnimateDiff-style mask shift, you name it.
The inputs that matter
Only two, and you'll fiddle with one of them:
images- your frames, as an IMAGE batch. Anything that outputs a batch works:Load Video(or the VHS pack), frames pulled out of AnimateDiff, or just stacked images. The frames should be the same size.width- strip width in pixels, default 1. This is the fun knob.1gives pixel-thin strips: the smoothest illusion, but the image looks like dense static and any small misalignment shows. Crank it to 5–20 and the strips get chunky and visible - closer to a legit lenticular print, but the animation gets coarser. Start at 1, go up only if the result looks broken or moiré-y.
The outputs are image (the interleaved still) and mask (the reveal mask), both IMAGE.
Installing it
The README keeps it blessedly simple, and there are no dependencies to chase - no requirements.txt, no model downloads, nothing. It only uses PIL, numpy, and torch, all of which ship with ComfyUI already.
- ComfyUI Manager: search "Animated-optical-illusions" (or "AOI") and install.
- Manual:
cd ComfyUI/custom_nodes && git clone https://github.com/ZHO-ZHO-ZHO/ComfyUI-Animated-optical-illusions, then restart ComfyUI.
Look under Zho模块组/AOI in the node menu.
Where people get burned
- Frames get silently dropped. The node slices each frame into
image_width / widthstrips, andinterleavetruncates to the shortest batch. If you feed more frames than there are strips per frame, the trailing frames vanish without a warning. With a 512px-wide image andwidth=1that's 512 strips - fine. But a 64px-wide image with 100 frames andwidth=2will quietly eat most of your animation. Fewer frames, or wider images, or biggerwidth, all fix it. - It's a still, not a GIF. A lot of people expect a video out. You get an image plus a mask; you have to supply the sliding. If you just stare at the output image, it looks like noise.
- All frames must be the same dimensions. The code assumes it; mismatched sizes will throw or produce garbage.
For a one-trick pack this is a genuinely tidy one - and refreshingly, it's the rare ZHO node with zero auto-downloading and zero heavy deps. If you're making a "secret animation" image for a profile picture or a party trick, it's a five-minute setup and hard to mess up once you respect the frame-count gotcha.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| width | INT | 11–100 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | IMAGE | — |