Nodes/Eric_Krea2/Eric Krea2 Paint (inpaint / outpaint)
ComfyUI Node

Eric Krea2 Paint (inpaint / outpaint)

Inpaint and outpaint where the pixels you keep actually stay put

By EricRollei·Created 4 months ago·Updated a day ago· 21
Eric Krea2 Paint (inpaint / outpaint)
  • image
  • mask
  • paint
  • vlm_image
  • canvas_preview
  • generated_mask
◄adapteranypaint►
◄pad_left0►
◄pad_right0►
◄pad_top0►
◄pad_bottom0►
◄seam_px32►
◄reference_max_edge384►
◄restore_s1on►
◄restore_s2auto►
◄restore_s3auto►
◄adapter_s11►
◄adapter_s20►
◄adapter_s30►
◄structure_release_sigma0.40►

Instruction editing took most of the jobs that masking used to do, and you should let it - describing an edit in a sentence beats painting a mask for almost everything. What instruction editing cannot do is leave the rest of the frame alone. It reasons about the whole image and emits a whole new one, so unmasked regions come back close to identical but not identical, and the drift compounds. That's the one claim masking still owns outright, and it's the reason to reach for Eric Krea2 Paint.

It gives you inpaint and outpaint in one node - arbitrary masks, canvas extension, or both - with kept regions pinned to the source at every stage. It's a bundle builder for the Ultra node's paint socket.

How it works

This is a reimplementation of yijunwang2's AnyPaint / Outpaint functional adapters against this pack's model. Three pieces do the work:

A small condition image - the canvas with every to-be-generated pixel filled in with the median known colour, capped at 384 px - is registered onto the target grid using fractional RoPE coordinates, and its keys/values are computed once at t = 0 into an isolated kv_cache.

Then the important bit: kept regions are pinned to the source in velocity space. Not composited at the end, pinned during sampling, which means every sampler - euler, res, deis, the hybrids, and even CFG passes - lands exactly on the source values in the kept region. Stage 1 Euler runs on the pack's fp32 solver when paint is active, matching the adapter author's pipeline bit-for-bit at that stage; the stock pipe's bf16 loop drifted.

Third, per-stage restore modes decide how long the pin holds once you move up in resolution, which is where the real thinking is. on pins every step. structure pins only while sigma is above structure_release_sigma (default 0.4), then lets the low-noise steps add detail - so a small source doesn't get upsampled blur forced on it, and identity still holds through the composition phase. auto is on when the source has at least that stage's resolution, else structure. off lets the stage rewrite. Defaults are on / auto / auto, and they're good defaults.

The inputs to set

Required is just image. Everything else is optional, which is unusual and means pure outpaint works with no mask at all.

  • mask - 1 = generate, ComfyUI mask-editor convention.
  • adapter - anypaint (arbitrary masks, inpaint + outpaint in one pass; needs the AnyPaint LoRA on the LoRA stack, S1 = 1, S2/S3 = 0), outpaint (older, rectangular only), none (training-free: pins the kept region and nothing else - fine for small inpaints).
  • pad_left / pad_right / pad_top / pad_bottom - outpaint canvas, in source-scale pixels.
  • seam_px (32) - the band around the mask that is regenerated rather than pinned, so the model can blend. Adapter default; don't fiddle until something's wrong.
  • reference_max_edge (384) - the condition image size, and 384 is the adapter's training contract. Change it to experiment, not to fix a problem.
  • restore_s1/s2/s3 and structure_release_sigma as above.
  • adapter_s1/s2/s3 - adapter conditioning per stage, default S1 only, because the adapter was trained at ≤1024 px targets.

Four outputs. paint goes to Ultra's paint socket. vlm_image goes into a Vision Prompt node's image input - that's how you get the prompt grounded in the canvas you're extending, and it's the wiring the README shows. canvas_preview shows the padded canvas before generation; generated_mask is a MASK you can reuse or inspect.

The recipe

Krea 2 Turbo, 8 steps, guidance 0. Stage 1 follows the canvas aspect at Ultra's s1_megapixels unless you set width/height explicitly, and crop_bottom is disabled for paint runs.

Then Eric Krea2 Paint Composite on the output if you need pixel-exact paste-back. AnyPaint doesn't strictly need it - the in-model pinning already holds the kept region - but it's the older Outpaint adapter's own post step, and it's where the source gets restored at native resolution if you've resized the result since.

Installing it

cd ComfyUI/custom_nodes
git clone https://github.com/EricRollei/Krea2_ComfyUI_Advanced

or Manager → Eric_Krea2. Hard requirements are the same as the rest of the pack: a diffusers containing Krea2Pipeline (pip install --upgrade --force-reinstall --no-deps git+https://github.com/huggingface/diffusers.git - the force flag is required), transformers>=4.57.0, Krea 2 weights in diffusers layout. For adapter = anypaint you also need the AnyPaint LoRA (krea2_anypaint_rank32) visible to the Multi-LoRA Stack.

Where it goes wrong

"nothing to generate: the mask is empty and there is no padding." The node is being honest - an all-zero mask with no output padding is a no-op. Paint something, or add pad.

Outpaint adapter with a non-rectangular mask prints a warning that it's rectangular-only. That's a limitation of that adapter, not a bug; use anypaint.

Composite softness. If the source is smaller than its area in the final result, the pasted pixels get upsampled and the node says so. Keep the source big enough, or accept a slightly soft preserved region.

CategoryEric/Krea2

Inputs (16)

NameTypeDefaultDescription
imageIMAGESource image. Kept regions are pinned to it at full resolution.
maskoptMASK1 = generate / edit (ComfyUI mask-editor convention). Source-sized or canvas-sized. Optional for pure outpaint.
adapteroptCOMBOanypaintanypaint: arbitrary masks, inpaint+outpaint (needs the AnyPaint LoRA on the LoRA stack). outpaint: older rectangular-only adapter. none: training-free - only pins the kept region (fine for small inpaints, weak for outpaint).
pad_leftoptINT00–4096Outpaint: pixels added on the left (source scale).
pad_rightoptINT00–4096—
pad_topoptINT00–4096—
pad_bottomoptINT00–4096—
seam_pxoptINT320–256Band around the mask that is regenerated (not pinned) so the model can blend. Canvas pixels; scaled per stage. Adapter default 32.
reference_max_edgeoptINT384128–1024Condition image size. 384 is the adapter's training contract - change only to experiment.
restore_s1optCOMBOonPin kept tokens to the source at Stage 1.
restore_s2optCOMBOautoauto: 'on' when the source has at least this stage's resolution, else 'structure'. on: pin kept regions every step (exact source pixels). structure: pin while sigma > structure_release_sigma (keeps composition and identity), then let the low-noise steps add detail - avoids forcing an upsampled small source's blur. off: S2 may rewrite kept regions.
restore_s3optCOMBOauto4 options: auto, on, structure, off
adapter_s1optFLOAT10–1Adapter reference conditioning at Stage 1 (1 = on, 0 = off).
adapter_s2optFLOAT00–1At Stage 2. Default off: the adapter was trained at <=1024 px targets.
adapter_s3optFLOAT00–1—
structure_release_sigmaoptFLOAT0.400–1restore 'structure' (and auto on upscale stages): kept regions are pinned while sigma is above this, free below. Lower = closer to the source, higher = more fresh detail (and more drift).

Outputs (4)

NameTypeDescription
paintKREA2_PAINT—
vlm_imageIMAGE—
canvas_previewIMAGE—
generated_maskMASK—