Bootstrap

ImageBlend 类实现解析

ImageBlend 类实现解析

1. 类和方法定义

文件头部的导入:

from .imagefunc import *

此行代码从当前目录的 imagefunc 模块中导入所有内容。假设 imagefunc 包含图像处理相关的函数和定义,例如混合模式、掩码转换工具等。这些工具将在 ImageBlend 类中使用。

类名和节点名称定义:

NODE_NAME = 'ImageBlend'

定义了一个常量 NODE_NAME,用于在日志消息中引用当前的图像混合节点。

2. 类的初始化

class ImageBlend:

    def __init__(self):
        pass

ImageBlend 类的构造函数目前不执行任何操作(只包含 pass),表明实例化此类不需要初始化特定的属性或执行其他启动任务。

3. 输入类型定义

@classmethod
def INPUT_TYPES(self):
    return {
        "required": {
            "background_image": ("IMAGE", ),
            "layer_image": ("IMAGE",),
            "invert_mask": ("BOOLEAN", {"default": True}),
            "blend_mode": (chop_mode,),
            "opacity": ("INT", {"default": 100, "min": 0, "max": 100, "step": 1}),
        },
        "optional": {
            "layer_mask": ("MASK",),
        }
    }

此方法定义了该节点所需和可选的输入类型:

  • 必需输入:

    • background_image: 背景图像。
    • layer_image: 需要叠加的图层图像。
    • invert_mask: 布尔值,用于指定是否应该反转图层掩膜。
    • blend_mode: 从 imagefunc 导入的 chop_mode,一种图像混合模式。
    • opacity: 图层的不透明度,范围从0到100。
  • 可选输入:

    • layer_mask: 定义图层可见性的掩膜。

4. 图像混合方法

def image_blend(self, background_image, layer_image, invert_mask, blend_mode, opacity, layer_mask=None):
    # 初始化列表
    b_images, l_images, l_masks, ret_images = [], [], [], []

    # 加载图像和掩膜
    for b in background_image:
        b_images.append(torch.unsqueeze(b, 0))
    for l in layer_image:
        l_images.append(torch.unsqueeze(l, 0))
        m = tensor2pil(l)
        if m.mode == 'RGBA':
            l_masks.append(m.split()[-1])
        else:
            l_masks.append(Image.new('L', m.size, 'white'))
    
    # 处理图层掩膜
    if layer_mask is not None:
        if layer_mask.dim() == 2:
            layer_mask = torch.unsqueeze(layer_mask, 0)
        l_masks = [tensor2pil(torch.unsqueeze(m, 0)).convert('L') if invert_mask else Image.new('L', m.size, 'white') for m in layer_mask]

    # 处理每一批图像
    max_batch = max(len(b_images), len(l_images), len(l_masks))
    for i in range(max_batch):
        background = b_images[i if i < len(b_images) else -1]
        layer = l_images[i if i < len(l_images) else -1]
        mask = l_masks[i if i < len(l_masks) else -1]
        
        # 混合操作
        canvas = tensor2pil(background).convert('RGB')
        layer_image = tensor2pil(layer).convert('RGB')
        comp = chop_image(canvas, layer_image, blend_mode, opacity)
        canvas.paste(comp, mask=mask)
        ret_images.append(pil2tensor(canvas))

    # 日志记录
    log(f"{NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish')
    
    return (torch.cat(ret_images, dim=0),)

这个方法实现了图像混合的核心功能,涉及以下步骤:

  • 初始化图像列表:为背景图像、图层图像和图层掩

膜分别创建列表。

  • 预处理图像:将每个图像张量转换为PIL图像,并为RGBA模式的图像提取透明通道作为掩膜。
  • 处理掩膜:如果提供了图层掩膜且需要反转,则反转掩膜;否则,为每个图层创建一个全白的掩膜。
  • 图像混合:对每个图像批次执行混合操作,使用指定的混合模式和透明度将图层图像合成到背景图像上。
  • 日志记录:记录处理过程的细节,如处理的图像数量。

5. 类和方法的注册

NODE_CLASS_MAPPINGS = {
    "LayerUtility: ImageBlend": ImageBlend
}

NODE_DISPLAY_NAME_MAPPINGS = {
    "LayerUtility: ImageBlend": "LayerUtility: ImageBlend"
}

这部分代码将 ImageBlend 类注册到一个更大的图像处理或节点系统中,允许通过指定的名称调用 ImageBlend 功能。这种注册机制通常用于插件式架构,允许动态地添加或修改功能。

;