Nodes/ComfyUI-Majoor-ImageOps/〽️ ImageOps Grain
ComfyUI Node

〽️ ImageOps Grain

Film grain that doesn't fight back — deterministic, seeded, and presets included

By MajoorWaldi·Created 8 months ago·Updated 8 days ago· 11
〽️ ImageOps Grain
  • image
  • mask
  • image
  • mask
bypassfalse
amount0.080
blend_modeadd
monochrometrue
animatedtrue
frame_length1
fps12.0
seed12345
invert_maskfalse

ImageOps Grain adds synthetic film grain to images or video batches - and it does the thing that separates a usable grain node from an annoying one: it's deterministic. Same seed, same grain, every run. No more re-rendering a shot and getting a different speckle pattern every time, which is exactly what breaks you out of using grain at all. It's from the ComfyUI-Majoor-ImageOps pack.

Why grain, seriously

Grain isn't just nostalgia. A touch of it does three practical things: it masks banding in smooth gradients (the #1 artifact in AI images), it hides the plastic-smooth look that reads as "AI," and it makes a still or video feel like it belongs in a filmic world. The trick is subtlety - this is a seasoning node, and the pack knows it, because the UI ships one-click film presets: Clean, Subtle, Cinema, B&W, and Heavy, each setting amount, blend mode, and monochrome together. Subtle or Cinema is where most jobs should live.

The controls

  • amount (0–1) - grain intensity. 0.05–0.15 is the sensible range; above that it starts looking like static.
  • blend_mode - add, overlay, or soft_light. overlay and soft_light sit better on images with real tonal range; add brightens and is more of a stylized choice.
  • monochrome (default on) - shared luma grain instead of independent RGB speckle. Monochrome reads as "film"; colored RGB grain reads as "video noise." Keep it on unless you're chasing a weird analog look.
  • animated + frame_length + fps - grain that changes per frame when you're animating a still. For a real clip, animated grain across the batch is what stops the image from looking like a frozen noise overlay.
  • seed - determinism. 🎲 button randomizes it when you want a different pattern.

Inputs are image and optional mask with invert_mask (grain only part of the frame - often the background, leaving skin clean). Outputs are image and mask.

Install

ComfyUI Manager (search "ComfyUI-Majoor-ImageOps"), or:

cd ComfyUI/custom_nodes
git clone https://github.com/MajoorWaldi/ComfyUI-Majoor-ImageOps

Restart and hard-refresh the browser (Ctrl+F5 / Cmd+Shift+R). No models, no extra deps.

The honest gotchas

Biggest mistake people make: treating amount like a linear dial and cranking it. 0.3 on a bright image is a lot. Start at 0.08 and trust the Subtle preset first. Second: if your still image's grain looks like a frozen speckle plate rather than living grain, animated is off - turn it on and set frame_length to match your output frames. And if you're stacking grain on top of an already-noisy image, you're just doubling the noise; the right move is usually denoise the source first, then grain it cleanly.

Categoryimage/imageops

Inputs (11)

NameTypeDefaultDescription
bypassBOOLEANfalse
amountFLOAT0.0800–1
blend_modeCOMBOadd3 options: add, overlay, soft_light
monochromeBOOLEANtrue
animatedBOOLEANtrue
frame_lengthINT11–256Number of output frames when animating grain over a still image.
fpsFLOAT12.01–120
seedINT123450–18446744073709550000
invert_maskBOOLEANfalse
imageoptIMAGE,VIDEOImages/Video input.
maskoptMASK

Outputs (2)

NameTypeDescription
imageIMAGE
maskMASK