Nodes/comfyui-kepri-nodes-pack/Kepri Framing Analysis (Border Contact + Margins)
ComfyUI Node

Kepri Framing Analysis (Border Contact + Margins)

Is your product touching the edge of the frame? This node decides

By wearekhepri·Created 5 months ago·Updated 2 months ago· 1
Kepri Framing Analysis (Border Contact + Margins)
  • mask
  • mask
  • framing
  • touches_top
  • touches_bottom
  • touches_left
  • touches_right
  • margin_top
  • margin_bottom
  • margin_left
  • margin_right
  • free_sides
  • framing_data
edge_tolerance_px2
contact_min_percent1.0

Here's the product-photo problem nobody warns you about: you've cut out the object, you need a 1:1 canvas, and the object touches the bottom edge of the original photo. Pad that side and you've painted a fake background band where the shoe was cropped by the frame. Crop it blindly and you might cut the object. KepriFramingAnalysis is the node that looks at the mask and tells the rest of the pipeline which sides are actually glued to the border - so padding and cropping happen per side instead of by guesswork.

It's part of the Kepri pack, built by a fashion-reseller startup for exactly this job: their automated background-removal and product-centering backend. Roughly 90% of shots are full_view - the object floats with room around it - but the moment one border is touched, that default padding is wrong and an adaptive rule has to kick in. This node detects and measures that. It doesn't do the pad/crop math itself; KepriImageFinalize does that. This one is the eyes.

Why it has to run before the bounding box

A mask→bbox node recenters the object, which destroys the "did it touch a wall?" information forever. So this node runs on the full-image mask before the bbox step, and its findings travel past that node in a packed string (see framing_data below). Placement: right after the chosen mask - post-fallback if you've chained it after KepriMaskAnalysis - and before the mask→bounding-box node.

How it decides

It binarizes the mask and scans a thin band along each edge, then applies two thresholds:

  • edge_tolerance_px (2) - active pixels within this many pixels of the edge count as "touching".
  • contact_min_percent (1.0) - the minimum % of the border's length that must actually be covered for it to count as contact, so one stray pixel doesn't flip the verdict.

Any border that clears both is touching; a side with no contact is free, and the free margin (edge→object, as a % of that dimension) is measured for the sides that matter.

Outputs

Most of them are for debugging, and one is the real wire:

  • framing - full_view (no contact) or details (≥1 contact).
  • touches_top/bottom/left/right - four booleans.
  • margin_top/bottom/left/right - free margin per side in %, 0.0 when touching.
  • free_sides - comma-joined, handy in a preview node.
  • framing_data - the packed string like details;T=1,B=0,L=0,R=0;mT=0,mB=60,mL=30,mR=30. Wire this single link into KepriImageFinalize's framing_data input and the finalize node goes fully adaptive: glued side gets zero padding and stays flush, free sides get the given padding with background extension, and an axis glued on both sides gets cover-cropped up to a safety cap. The mask output is a passthrough, so the node doesn't disturb your existing wiring.

Gotchas and install

An empty mask doesn't crash it - it returns full_view, all margins at 100, all sides free, and leaves the degenerate case to KepriMaskAnalysis upstream. Batched masks (multi-box detection before a merge) are unioned across the batch, so the verdict never depends on detection order.

It's part of comfyui-kepri-nodes-pack: ComfyUI Manager → search "comfyui-kepri-nodes-pack", or:

cd ComfyUI/custom_nodes
git clone https://github.com/wearekhepri/comfyui-kepri-nodes-pack

Restart and refresh; it appears under Kepri/Background. No extra dependencies, no models to download. One small trap: the README's clone snippet uses the wrong repo URL (comfyui-kepri.git), so copy the command above.

CategoryKepri/Background

Inputs (3)

NameTypeDefaultDescription
maskMASK
edge_tolerance_pxINT20–64An object counts as 'touching' a border if active pixels lie within this many px of the edge.
contact_min_percentFLOAT1.00–100Minimum % of the border length that must be covered to count as contact (ignores a stray pixel).

Outputs (12)

NameTypeDescription
maskMASK
framingSTRING
touches_topBOOLEAN
touches_bottomBOOLEAN
touches_leftBOOLEAN
touches_rightBOOLEAN
margin_topFLOAT
margin_bottomFLOAT
margin_leftFLOAT
margin_rightFLOAT
free_sidesSTRING
framing_dataSTRING