Nodes/BrainDead Nodes/BD Crop and Center
ComfyUI Node

BD Crop and Center

Give every part a shared pivot — the crop that keeps game textures aligned

By BizaNator·Created 8 months ago·Updated 3 days ago· 15
BD Crop and Center
  • image
  • mask
  • image
  • mask
  • transform
anchorcenter
canvas_width0
canvas_height0
pad0
threshold0.02
scale_to_fitfalse
background_hex#000000
flatten_to_masktrue

When you pack several isolated parts into R/G/B channels of one game texture, they only line up in-engine if every part sits on the same pivot - the same anchor point on the same canvas. If each part is cropped to its own bounding box with its own origin, the engine extracts them at different positions and the assembled character falls apart. BD CropAndCenter solves that: it crops an image to its content's bounding box, then re-places it at original scale onto a fixed canvas at a chosen anchor. Every part gets a common pivot, so they overlap correctly when channel-packed or atlased. The node description is explicit about the distinction: this is not the same as BD Crop To Mask, which crops and resizes to a square.

The node description also names its ancestor: "like AILab Crop-to-Object." Familiar territory, with the centering layer added on top.

The inputs that matter

  • image - the source.
  • mask - defines the crop region via its bounding box. If absent, the bbox comes from the image's alpha (RGBA) or its difference from the border background color.
  • canvas_width / canvas_height - the mode switch. Both 0 → output the tight crop (just the bbox region). Either > 0 → place the crop onto a canvas of that size at the anchor (if only one is > 0, the other uses the input size). This is the centering option.
  • anchor - placement on the canvas: center (the shared-pivot default), edges, or corners.
  • scale_to_fit - canvas mode only. ON scales the crop to fit the canvas (longest side → canvas, aspect preserved, up or down). OFF keeps original pixel scale and only re-pivots.
  • pad - margin in pixels added around the bbox before cropping.
  • threshold - mask/alpha value above which a pixel counts as content.
  • flatten_to_mask - ON (default) shows content only inside the mask, background color filling the rest; OFF gives the raw rectangular crop, exactly like AILab.
  • background_hex - fill for padded/masked-out regions, default #000000.

Outputs: image (the cropped/recentered result), mask (its mask), and transform - a STRING of JSON describing the source bbox, placement, and scale. That transform output is genuinely useful if you're recording where each part landed for a build script or an engine-side layout.

The workflow shape

The pack's Game-Engine Packing flow: isolate parts → balance luma → crop & center each onto the same canvas at the same anchor → pack into R/G/B. Each part passes through this node with identical canvas and anchor settings, and because they're all at original scale on a shared pivot, they assemble perfectly when channel-packed. That's the "shared pivot, no bleed" workflow the pack advertises.

Installing it

Part of BizaNator/ComfyUI-BrainDead (BrainDeadGuild). ComfyUI Manager → search "BrainDead" → install, or:

cd ComfyUI/custom_nodes
git clone https://github.com/BizaNator/ComfyUI-BrainDead
cd ComfyUI-BrainDead
pip install -r requirements.txt

Restart; it's under 🧠BrainDead/Segmentation.

Gotchas

The canvas-width/height mode switch is the thing people trip on: set both to 0 expecting centering and you get a tight crop, no canvas - that's not a bug, that's the two modes. And scale_to_fit changes the contract: with it off, parts keep their true pixel scale (important when you need the engine to see sizes as-is); with it on, everything gets normalized to fit, which is convenient but destroys relative size. Also note the bbox source chain: mask → alpha → border-difference. If your image has neither alpha nor a contrasting border, the "content" detection has nothing to work with, so wire the mask. Finally, the transform output is easy to ignore and worth keeping when you're automating: it's the ground truth of where the part actually landed.

Category🧠BrainDead/Segmentation

Inputs (10)

NameTypeDefaultDescription
imageIMAGE
maskoptMASKMask defining the crop region (its bounding box). If absent, the bbox is taken from the image's alpha (RGBA) or its difference from the border bg.
anchoroptCOMBOcenterPlacement on the canvas (only used when canvas_width/height > 0). center = shared pivot; top/bottom/left/right + corners anchor by that edge.
canvas_widthoptINT00–81920 = output the TIGHT CROP (no canvas). >0 = place the crop on a canvas this wide at the anchor. (If only one of width/height is >0, the other uses the input size.)
canvas_heightoptINT00–81920 = tight crop (no canvas). >0 = canvas height for centering.
padoptINT00–1024Pixels of margin added around the mask bbox before cropping (AILab-style padding).
thresholdoptFLOAT0.020–1Mask/alpha value above which a pixel counts as content (for the bbox).
scale_to_fitoptBOOLEANfalseCanvas mode only. On = scale the crop to FIT the canvas (longest side → canvas), preserving aspect (up or down), then anchor. Off = keep original pixel scale (re-pivot only).
background_hexoptSTRING#000000Background fill for masked-out / padded regions.
flatten_to_maskoptBOOLEANtrueOn = content shows only inside the mask; the background colour fills the rest of the crop (and alpha = mask for RGBA). Off = output the raw rectangular crop (exactly like AILab Crop-to-Object).

Outputs (3)

NameTypeDescription
imageIMAGE
maskMASK
transformSTRING