| import torch
|
|
|
| class Canvas_Crop:
|
| """
|
| Reduce the canvas of an image by cropping pixels from each side.
|
|
|
| Inputs
|
| ------
|
| image : IMAGE
|
| Torch tensor [B, H, W, C], C=3 (RGB) or C=4 (RGBA), values in [0, 1].
|
| If RGB is provided, it will be converted to RGBA by appending an opaque alpha channel.
|
|
|
| left, right, up, down : INT
|
| Number of pixels to remove from the corresponding side.
|
|
|
| Output
|
| ------
|
| image : IMAGE
|
| Torch tensor [B, H - (up+down), W - (left+right), 4] (RGBA).
|
| """
|
|
|
| @classmethod
|
| def INPUT_TYPES(s):
|
| return {
|
| "required": {
|
| "image": ("IMAGE",),
|
| "left": ("INT", {"default": 0, "min": 0, "max": 16384, "step": 1}),
|
| "right": ("INT", {"default": 0, "min": 0, "max": 16384, "step": 1}),
|
| "up": ("INT", {"default": 0, "min": 0, "max": 16384, "step": 1}),
|
| "down": ("INT", {"default": 0, "min": 0, "max": 16384, "step": 1}),
|
| }
|
| }
|
|
|
| RETURN_TYPES = ("IMAGE",)
|
| RETURN_NAMES = ("image",)
|
| FUNCTION = "crop"
|
| CATEGORY = "image/canvas"
|
|
|
| def _ensure_rgba(self, img: torch.Tensor) -> torch.Tensor:
|
|
|
| if img.dim() != 4:
|
| raise ValueError(f"Expected image tensor [B, H, W, C], got shape {tuple(img.shape)}")
|
|
|
| c = img.shape[-1]
|
| if c == 4:
|
| return img
|
| elif c == 3:
|
|
|
| alpha = torch.ones((*img.shape[:-1], 1), dtype=img.dtype, device=img.device)
|
| return torch.cat([img, alpha], dim=-1)
|
| elif c > 4:
|
|
|
| return img[..., :4]
|
| else:
|
| raise ValueError("Expected RGB or RGBA image with 3 or 4 channels.")
|
|
|
| def crop(self, image: torch.Tensor, left: int, right: int, up: int, down: int):
|
| rgba = self._ensure_rgba(image)
|
| b, h, w, _ = rgba.shape
|
|
|
|
|
| left = max(0, int(left))
|
| right = max(0, int(right))
|
| up = max(0, int(up))
|
| down = max(0, int(down))
|
|
|
|
|
| if left + right >= w:
|
| raise ValueError(
|
| f"Crop too wide: left({left}) + right({right}) >= image width({w})."
|
| )
|
| if up + down >= h:
|
| raise ValueError(
|
| f"Crop too tall: up({up}) + down({down}) >= image height({h})."
|
| )
|
|
|
|
|
| y0 = up
|
| y1 = h - down
|
| x0 = left
|
| x1 = w - right
|
|
|
|
|
| out = rgba[:, y0:y1, x0:x1, :]
|
| return (out,)
|
|
|
|
|
|
|
| NODE_CLASS_MAPPINGS = {
|
| "Canvas_Crop": Canvas_Crop
|
| }
|
|
|
| NODE_DISPLAY_NAME_MAPPINGS = {
|
| "Canvas_Crop": "Canvas_Crop (Salia)",
|
| }
|
|
|