Nodes/ComfyUI-Pixel-Locker/PixelLockSampler
ComfyUI Node

PixelLockSampler

A KSampler that actually keeps what you told it to keep

By Bogyie·Created 4 months ago·Updated 4 months ago· 0
PixelLockSampler
  • model
  • positive
  • negative
  • pixel_lock_mask
  • original_image
  • vae
  • original_latent
  • latent
seed0
steps20
cfg8.0
sampler_name
scheduler
boundary_strength0.35
denoise1.00
edit_strength0.85

This is the heart of the Pixel Locker pack: a KSampler-style sampler built for masked inpainting, and it does the two things the built-in sampler is bad at. It starts from your real image's latent instead of an empty one, and it locks protected regions back in at the end rather than hoping the model behaved. If MaskBuilder is the map, this is the engine.

Why reach for it instead of the stock KSampler with a noise mask? The stock approach denoises from an empty latent and can smear protected structure, because VAE latents don't map neatly back onto pixels. This node takes the original image's latent as ground truth, adds noise only where editing is allowed, and re-blends the original latent into the protected zones as it finishes. It's masked img2img done the way the community's been asking for it since the "please composite your image" era - except the protection happens inside sampling, not as an afterthought.

The inputs that matter

Most of it reads like a normal sampler - model, positive, negative, seed, steps (20), cfg (8), sampler_name, scheduler. The Pixel Locker-specific dials:

  • edit_strength (default 0.85) - how hard the full_edit region gets re-denoised. The README's guidance: when replacing clothing or other large regions, start around 0.75–0.9. Lower it and the edit region stays closer to the original; raise it and you're effectively re-rolling that area.
  • boundary_strength (default 0.35) - how much of the original survives in the soft_keep band during the latent lock. Keep it consistent with the same field on the composite node so both stages agree on the feather.
  • denoise (default 1.0) - the usual strength dial for the whole pass.

Three optional inputs, and you must provide one of these pairs: original_latent (a LATENT, ideally from a VAEEncode of the original image - the README says this is the faster path), or original_image + vae, which the sampler encodes itself. Don't wire an EmptyLatentImage in - the README is explicit that this sampler ignores an incoming base latent; it always starts from the original image's latent. Skip both and it throws a "needs original_latent or original_image+vae" error.

How it works

From the source, it builds a noise_mask from full_edit × edit_strength plus soft_keep × (1 − boundary_strength), seeds some noise, and samples starting from the encoded original latent with that mask. Then it blends the result back toward the original latent with an alpha of hard_keep + soft_keep × boundary_strength. So you get two layers of protection: only editable regions are denoised during sampling, and the final latent is pulled back toward the original in every protected zone.

One honest caveat: latent-space protection is not pixel-perfect. The VAE round trip is lossy, so exact RGB preservation only happens at the composite stage. Always follow this with PixelLockDecodeComposite (or a VAEDecode into PixelLockComposite) - that's not optional if "keep everything outside the mask identical" is the actual requirement.

Output and workflow

One output: latent. Wire it into PixelLockDecodeComposite with the same pixel_lock_mask and boundary_strength, or into a plain VAEDecode plus PixelLockComposite if you already have a decode step. Any standard checkpoint works - there's no special inpainting model required, which keeps the pack genuinely lightweight.

CategoryPixel Locker

Inputs (15)

NameTypeDefaultDescription
modelMODEL
seedINT00–18446744073709550000
stepsINT201–10000
cfgFLOAT8.00–100
sampler_nameCOMBO44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38
schedulerCOMBO9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3
positiveCONDITIONING
negativeCONDITIONING
pixel_lock_maskPIXEL_LOCK_MASK
boundary_strengthFLOAT0.350–1
denoiseFLOAT1.000–1
edit_strengthFLOAT0.850–1
original_imageoptIMAGE
vaeoptVAE
original_latentoptLATENT

Outputs (1)

NameTypeDescription
latentLATENT