Nodes/ComfyUI-AffineImage/🔄 AffineTransform2img
ComfyUI Node

🔄 AffineTransform2img

Putting your design on a screen without re-rolling img2img

By GuardSkill·Created about a year ago·Updated 10 months ago· 6
🔄 AffineTransform2img
  • background_image
  • source_image
  • mapped_image
  • cropped_screen
  • screen_mask
four_points
blend_modereplace
opacity1.00
crop_to_screentrue

Want to see your design on a laptop screen, a book cover, or a storefront before you generate anything else? This is the deterministic way to do it. PerspectiveScreenMapper is the second half of ComfyUI-AffineImage: you hand it a background image, a source image, and four corner points, and it does a real perspective transform to place the source exactly inside that quadrilateral. No prompt roulette, no img2img drift - just geometry.

Screen mapping is only the demo. Any four-point surface in a photo - a billboard, a wall, a picture frame, a phone face-down on a table - works the same.

How it works

Under the hood it's plain OpenCV. The source image's four corners (top-left, top-right, bottom-right, bottom-left) are mapped to your four target points via cv2.getPerspectiveTransform, the warp is applied with a transparent border, and a polygon mask is built from the target quad. Then it composites using one of four blend modes.

That's it. This is the "cheap, fast, exact" end of the compositing spectrum - the thing the KB files call infrastructure rather than a topic, because once it works you just use it.

Inputs that matter

  • background_image - the photo with the surface you're mapping onto.
  • source_image - the content being placed.
  • four_points - a STRING. This must come from the selector node's four_points output; it's a JSON string of coordinates, not something you eyeball.
  • blend_mode - replace, overlay, multiply, or screen (default replace).
  • opacity - 0 to 1, but read the trap below.
  • crop_to_screen - default on; also returns the mapped region cropped to the quad's bounding box.

Outputs are mapped_image (the full composite), cropped_screen (the mapped region alone - handy if you want to feed it to a detailer), and screen_mask (the quad as a MASK).

Installing it

Same pack as the selector, so installing one installs both. Use ComfyUI Manager (search ComfyUI-AffineImage) or:

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

Restart ComfyUI. Dependencies are opencv-python, pillow, and numpy - no models, no GPU installs beyond what ComfyUI already needs.

Where people get burned

  • The silent no-op is the big one. If four_points isn't a valid four-point JSON, the node prints "needs 4 points" to the console and returns the background image untouched. No red node, no error toast - it just looks like nothing happened. If that's you, re-run the selector and make sure all four points are set, then check the wire.
  • Point order strikes again. The warp assumes the same top-left → top-right → bottom-right → bottom-left order you clicked in the selector. Rotated or mirrored output means the order drifted.
  • opacity does nothing in replace mode. The code only applies it in the overlay/multiply/screen path. If you want to fade the paste, switch off replace - a surprisingly easy thing to stare at and wonder why the slider isn't working.
  • replace hard-cuts the quad edges, so seams show. Feather the mask or run a color match (ComfyUI's Color Match Image is the right tool) so the pasted region sits in the surrounding light.
  • The warp is linear interpolation, so mapping a small source onto a big area comes out soft. Up-scale the source first if it's going to stretch.

The workflow shape people land on: map the design in, then take cropped_screen or screen_mask into an inpainting/detailing pass to restore reflections, shadows, or foreground that the paste covers - that's exactly what the pack's "add hands" example does. The mapper isn't the node that makes the scene convincing; it's the node that makes the placement exact, so you only have to fake the lighting, not the geometry.

CategoryImageNodes

Inputs (6)

NameTypeDefaultDescription
background_imageIMAGE
source_imageIMAGE
four_pointsSTRING
blend_modeoptCOMBOreplace4 options: replace, overlay, multiply, screen
opacityoptFLOAT1.000–1
crop_to_screenoptBOOLEANtrue

Outputs (3)

NameTypeDescription
mapped_imageIMAGE
cropped_screenIMAGE
screen_maskMASK