Image Paste Crop by Location¶
Documentation¶
- Class name:
Image Paste Crop by Location
- Category:
WAS Suite/Image/Process
- Output node:
False
This node specializes in pasting a cropped image onto a specified location within another image, allowing for blending and sharpening adjustments. It provides the capability to seamlessly integrate a cropped image into a larger canvas, with options to fine-tune the integration through blending gradients and sharpening effects, enhancing the overall composition.
Input types¶
Required¶
image
- The base image onto which the cropped image will be pasted. It serves as the canvas for the operation, determining the final image's dimensions and serving as the background for the pasted crop.
- Comfy dtype:
IMAGE
- Python dtype:
PIL.Image
crop_image
- The cropped image to be pasted onto the base image. This image is the focal point of the operation, and its placement and appearance adjustments (blending and sharpening) significantly influence the outcome.
- Comfy dtype:
IMAGE
- Python dtype:
PIL.Image
top
- The top coordinate where the cropped image will be placed on the base image. It determines the vertical positioning of the crop.
- Comfy dtype:
INT
- Python dtype:
int
left
- The left coordinate where the cropped image will be placed on the base image. It determines the horizontal positioning of the crop.
- Comfy dtype:
INT
- Python dtype:
int
right
- The right boundary for the cropping operation, affecting how the image blends on the right side.
- Comfy dtype:
INT
- Python dtype:
int
bottom
- The bottom boundary for the cropping operation, affecting how the image blends on the bottom side.
- Comfy dtype:
INT
- Python dtype:
int
crop_blending
- The degree to which the cropped image blends with the base image at the edges, creating a gradient transition. This parameter allows for a smoother integration of the crop into the base image.
- Comfy dtype:
FLOAT
- Python dtype:
float
crop_sharpening
- The intensity of the sharpening effect applied to the cropped image. This parameter can enhance the details of the crop, making it stand out more or blend better with the base image.
- Comfy dtype:
INT
- Python dtype:
int
Output types¶
image
- Comfy dtype:
IMAGE
- The resulting image after the cropped image has been pasted, blended, and optionally sharpened onto the base image. It represents the final composition, showcasing the integrated appearance of the crop within the larger canvas.
- Python dtype:
PIL.Image
- Comfy dtype:
Usage tips¶
- Infra type:
CPU
- Common nodes: unknown
Source code¶
class WAS_Image_Paste_Crop_Location:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"crop_image": ("IMAGE",),
"top": ("INT", {"default":0, "max": 10000000, "min":0, "step":1}),
"left": ("INT", {"default":0, "max": 10000000, "min":0, "step":1}),
"right": ("INT", {"default":256, "max": 10000000, "min":0, "step":1}),
"bottom": ("INT", {"default":256, "max": 10000000, "min":0, "step":1}),
"crop_blending": ("FLOAT", {"default": 0.25, "min": 0.0, "max": 1.0, "step": 0.01}),
"crop_sharpening": ("INT", {"default": 0, "min": 0, "max": 3, "step": 1}),
}
}
RETURN_TYPES = ("IMAGE", "IMAGE")
FUNCTION = "image_paste_crop_location"
CATEGORY = "WAS Suite/Image/Process"
def image_paste_crop_location(self, image, crop_image, top=0, left=0, right=256, bottom=256, crop_blending=0.25, crop_sharpening=0):
result_image, result_mask = self.paste_image(tensor2pil(image), tensor2pil(crop_image), top, left, right, bottom, crop_blending, crop_sharpening)
return (result_image, result_mask)
def paste_image(self, image, crop_image, top=0, left=0, right=256, bottom=256, blend_amount=0.25, sharpen_amount=1):
image = image.convert("RGBA")
crop_image = crop_image.convert("RGBA")
def inset_border(image, border_width=20, border_color=(0)):
width, height = image.size
bordered_image = Image.new(image.mode, (width, height), border_color)
bordered_image.paste(image, (0, 0))
draw = ImageDraw.Draw(bordered_image)
draw.rectangle((0, 0, width-1, height-1), outline=border_color, width=border_width)
return bordered_image
img_width, img_height = image.size
# Ensure that the coordinates are within the image bounds
top = min(max(top, 0), img_height)
left = min(max(left, 0), img_width)
bottom = min(max(bottom, 0), img_height)
right = min(max(right, 0), img_width)
crop_size = (right - left, bottom - top)
crop_img = crop_image.resize(crop_size)
crop_img = crop_img.convert("RGBA")
if sharpen_amount > 0:
for _ in range(sharpen_amount):
crop_img = crop_img.filter(ImageFilter.SHARPEN)
if blend_amount > 1.0:
blend_amount = 1.0
elif blend_amount < 0.0:
blend_amount = 0.0
blend_ratio = (max(crop_size) / 2) * float(blend_amount)
blend = image.copy()
mask = Image.new("L", image.size, 0)
mask_block = Image.new("L", crop_size, 255)
mask_block = inset_border(mask_block, int(blend_ratio/2), (0))
Image.Image.paste(mask, mask_block, (left, top))
blend.paste(crop_img, (left, top), crop_img)
mask = mask.filter(ImageFilter.BoxBlur(radius=blend_ratio/4))
mask = mask.filter(ImageFilter.GaussianBlur(radius=blend_ratio/4))
blend.putalpha(mask)
image = Image.alpha_composite(image, blend)
return (pil2tensor(image), pil2tensor(mask.convert('RGB')))