commit DistortDisplace node
This commit is contained in:
@@ -2149,6 +2149,19 @@ On the basis of MaskEdgeUltraDetail, the following changes have been made:
|
||||
* max_megapixels: Set the maximum size for VitMate operations.
|
||||
|
||||
|
||||
### <a id="table1">MaskEdgeUltraDetailV3</a>
|
||||
The upgraded version of MaskEdgeUltraDetailV2 to processes different partitions through inputting trimap masks, generating an overall mask that includes more refined and translucent parts.
|
||||

|
||||
|
||||
On the basis of MaskEdgeUltraDetailV2, the following changes have been made:
|
||||

|
||||
* transparent_trimap: Using different vitmatte parameters within this area can generate more refined matte mask. It is typically used to handle areas such as translucent objects or hair strands.
|
||||
* mask_edge_erode: The edge of the mask part erodes inwardly. The larger the value, the greater the range of inward repair.
|
||||
* mask_edge_dilate: The edge of the mask expands outward. The larger the value, the greater the outward repair range.
|
||||
* transparent_trimap_edge_erode: The edge of the transparent_trimap mask erodes inwardly. The larger the value, the greater the range of inward correction.
|
||||
* transparent_trimap_edge_dilate: The edge of the transparent_trimap mask expands outward. The larger the value, the greater the outward repair range.
|
||||
* trimap_blur: The degree of blur at the edge where the trimap mask and the mask are fused.
|
||||
|
||||
### <a id="table1">MaskByColor</a>
|
||||
|
||||
Generate a mask based on the selected color.
|
||||
@@ -2522,6 +2535,27 @@ Node Options:
|
||||
* grain_scale: Noise size.
|
||||
* grain_sat: Color saturation of noise.
|
||||
|
||||
### <a id="table1">DistortDisplace</a>
|
||||
Generate displacement deformation effects for material images.
|
||||

|
||||
|
||||
Node Options:
|
||||

|
||||
* image: The original image, with material distortion based on the grayscale information of this image.
|
||||
* material_image: Material image. The size of this image should be consistent with that of the image, otherwise it will be resized forcibly.
|
||||
* mask: Optional mask input. The output will only include the deformed result of the map in the masked part.
|
||||
* distort_strength: The strength of distortion.
|
||||
* smoothness: The smoothness of distortion.
|
||||
* anit_aliasing: The value of anti-aliasing. Higher values will result in a significant decrease in generation speed.
|
||||
* shadow_blend_mode: The shadow part blending mode.
|
||||
* shadow_strength: The shadow part blending opacity.
|
||||
* highlight_blend_mode: The highlight part blending mode.
|
||||
* highlight_strength: The highlight part blending opacity.
|
||||
|
||||
Outputs:
|
||||
* image: The output image.
|
||||
* displaced_material: The deformation result of the material image.
|
||||
|
||||
## Annotation for <a id="table1">notes</a>
|
||||
|
||||
<sup>1</sup> The layer_image, layer_mask and the background_image(if have input), These three items must be of the same size.
|
||||
|
||||
@@ -128,6 +128,8 @@ os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
|
||||
## 更新说明
|
||||
<font size="4">**如果本插件更新后出现依赖包错误,请双击运行插件目录下的```install_requirements.bat```(官方便携包),或 ```install_requirements_aki.bat```(秋叶整合包) 重新安装依赖包。
|
||||
|
||||
* 添加 [DistortDisplace](#DistortDisplace) 节点, 为材质图片生成置换变形效果。
|
||||
* 添加 [MaskEdgeUltraDetailV3](#MaskEdgeUltraDetailV3) 节点, 通过输入trimap遮罩对不同分区处理,生成包括更加精细半透明部分的整体遮罩。
|
||||
* 添加 [ImageCompositeHandleMask](#ImageCompositeHandleMask) 节点, 用于生成局部羽化遮罩以及对应的裁切数据。
|
||||
* 添加 [DrawRoundedRectangle](#DrawRoundedRectangle) 节点, 用于生成圆角矩形遮罩。
|
||||
* 添加 [FluxKontextImageScale](#FluxKontextImageScale) 节点,基于官方节点修改,用于将图像大小调整为更适合FluxKontext的大小。对于非标准宽高比的图像,自动调整比例以保持所有画面信息。
|
||||
@@ -1933,6 +1935,18 @@ MaskEdgeUltraDetail的V2升级版,增加了VITMatte边缘处理方法,此方
|
||||
* device: 设置是否使用cuda。
|
||||
* max_megapixels: 设置vitmatte运算的最大尺寸。
|
||||
|
||||
### <a id="table1">MaskEdgeUltraDetailV3</a>
|
||||
MaskEdgeUltraDetailV2的升级版,通过输入trimap遮罩对不同分区处理,生成包括更加精细半透明部分的整体遮罩。
|
||||

|
||||
|
||||
在MaskEdgeUltraDetailV2的基础上做了如下改变:
|
||||

|
||||
* transparent_trimap: 此区域范围使用不同的vitmatte参数,可生成更精细的局部遮罩。通常用于处理半透明物体或头发丝等区域。
|
||||
* mask_edge_erode: mask遮罩部分的边缘向内侵蚀范围。数值越大,向内修复的范围越大。
|
||||
* mask_edge_dilate: mask遮罩部分的边缘向外扩张范围。数值越大,向外修复的范围越大。
|
||||
* transparent_trimap_edge_erode: transparent_trimap遮罩部分的边缘向内侵蚀范围。数值越大,向内修复的范围越大。
|
||||
* transparent_trimap_edge_dilate: transparent_trimap遮罩部分的边缘向外扩张范围。数值越大,向外修复的范围越大。
|
||||
* trimap_blur: trimap遮罩与mask遮罩融合边缘的模糊程度。
|
||||
|
||||
### <a id="table1">MaskByColor</a>
|
||||
根据颜色生成遮罩。
|
||||
@@ -2261,6 +2275,27 @@ Film节点的升级版, 在之前基础上增加了fastgrain方法,生成噪
|
||||
* grain_sat: 噪声的色彩饱和度。
|
||||
|
||||
|
||||
### <a id="table1">DistortDisplace</a>
|
||||
为材质图片生成置换变形效果。
|
||||

|
||||
|
||||
节点选项说明:
|
||||

|
||||
* image: 原始图片,材质变形基于此图片的灰度信息。
|
||||
* material_image: 材质图片。 注意此图片大小要与image一致,否则将强行转换尺寸。
|
||||
* mask: 可选遮罩输入。将输出仅包括在遮罩部分的贴图变形结果。
|
||||
* distort_strength: 变形强度。
|
||||
* smoothness: 变形的平滑度。
|
||||
* anit_aliasing: 抗锯齿。更高的数值将导致生成速度明显下降。
|
||||
* shadow_blend_mode: 暗部混合模式。
|
||||
* shadow_strength: 暗部混合强度。
|
||||
* highlight_blend_mode: 亮部混合模式。
|
||||
* highlight_strength: 亮部混合强度。
|
||||
|
||||
输出说明:
|
||||
* image: 输出图片。
|
||||
* displaced_material: 材质图片变形结果。
|
||||
|
||||
## <a id="table1">节点注解</a>
|
||||
<sup>1</sup> image、mask和background_image(如果有输入)这三项必须是相同的尺寸。
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 786 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 200 KiB |
@@ -0,0 +1,101 @@
|
||||
import copy
|
||||
import torch
|
||||
import numpy as np
|
||||
from .imagefunc import log, pil2tensor, tensor2pil, chop_image_v2, chop_mode_v2, fit_resize_image, displacement_image
|
||||
|
||||
|
||||
class LS_DistortDisplace:
|
||||
|
||||
def __init__(self):
|
||||
self.NODE_NAME = 'DistortDisplace'
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(self):
|
||||
shadow_blendmode_list = ['linear burn', "multiply"]
|
||||
highlight_blendmode_list = ['screen', 'linear dodge(add)']
|
||||
shadow_blendmode_list = shadow_blendmode_list + [x for x in chop_mode_v2 if x not in shadow_blendmode_list]
|
||||
highlight_blendmode_list = highlight_blendmode_list + [x for x in chop_mode_v2 if x not in highlight_blendmode_list]
|
||||
return {
|
||||
"required": {
|
||||
"image": ("IMAGE", ), #
|
||||
"material_image": ("IMAGE",), #
|
||||
"distort_strength": ("FLOAT", {"default": 50, "min": -999, "max": 999, "step": 0.1}),
|
||||
"smoothness": ("INT", {"default": 8, "min": 0, "max": 99, "step": 1}),
|
||||
"anti_aliasing": ("INT", {"default": 2, "min": 1, "max": 16, "step": 1}),
|
||||
"shadow_blend_mode": (shadow_blendmode_list,),
|
||||
"shadow_strength": ("INT", {"default": 75, "min": 0, "max": 100, "step": 1}), # 透明度
|
||||
"highlight_blend_mode": (highlight_blendmode_list,),
|
||||
"highlight_strength": ("INT", {"default": 30, "min": 0, "max": 100, "step": 1}),
|
||||
},
|
||||
"optional": {
|
||||
"mask": ("MASK",), #
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE", "IMAGE",)
|
||||
RETURN_NAMES = ("image", "displaced_material")
|
||||
FUNCTION = 'distort_displace'
|
||||
CATEGORY = '😺dzNodes/LayerFilter'
|
||||
|
||||
def distort_displace(self, image, material_image, distort_strength, smoothness, anti_aliasing,
|
||||
shadow_blend_mode, shadow_strength, highlight_blend_mode, highlight_strength,
|
||||
mask=None):
|
||||
|
||||
m_images = []
|
||||
i_images = []
|
||||
i_masks = []
|
||||
ret_images = []
|
||||
displaced_images = []
|
||||
|
||||
for m in material_image:
|
||||
m_images.append(torch.unsqueeze(m, 0))
|
||||
for i in image:
|
||||
i_images.append(torch.unsqueeze(i, 0))
|
||||
if mask is not None:
|
||||
if mask.dim() == 2:
|
||||
mask = torch.unsqueeze(mask, 0)
|
||||
for m in mask:
|
||||
i_masks.append(torch.unsqueeze(m, 0))
|
||||
|
||||
max_batch = max(len(m_images), len(i_images), len(i_masks))
|
||||
for i in range(max_batch):
|
||||
m_img = m_images[i] if i < len(m_images) else m_images[-1]
|
||||
_image = tensor2pil(m_img).convert('RGB')
|
||||
i_img = i_images[i] if i < len(i_images) else i_images[-1]
|
||||
_grayscale = tensor2pil(i_img)
|
||||
|
||||
log(f"{self.NODE_NAME} processing:")
|
||||
|
||||
displaced_image = displacement_image(_image, _grayscale, distort_strength, smoothness, anti_aliasing)
|
||||
|
||||
orig_image = tensor2pil(i_img)
|
||||
if shadow_strength > 0:
|
||||
ret_image = chop_image_v2(orig_image, displaced_image, shadow_blend_mode, shadow_strength)
|
||||
else:
|
||||
ret_image = orig_image
|
||||
if highlight_strength > 0:
|
||||
ret_image = chop_image_v2(ret_image, displaced_image, highlight_blend_mode, highlight_strength)
|
||||
|
||||
if mask is not None:
|
||||
i_msk = i_masks[i] if i < len(i_masks) else i_masks[-1]
|
||||
_mask = tensor2pil(i_msk).convert('L')
|
||||
if _mask.size != displaced_image.size:
|
||||
_mask = fit_resize_image(_mask, displaced_image.width, displaced_image.height,'fill', Image.LANCZOS)
|
||||
log(f"Warning: {self.NODE_NAME} mask mismatch, fixed to image size!", message_type='warning')
|
||||
orig_image.paste(ret_image, mask=_mask)
|
||||
ret_image = orig_image
|
||||
|
||||
ret_images.append(pil2tensor(ret_image))
|
||||
displaced_images.append(pil2tensor(displaced_image))
|
||||
log(f"{self.NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish')
|
||||
|
||||
return (torch.cat(ret_images, dim=0), torch.cat(displaced_images, dim=0),)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"LayerFilter: DistortDisplace": LS_DistortDisplace,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"LayerFilter: DistortDisplace": "LayerFilter: Distort Displace",
|
||||
}
|
||||
+55
-52
@@ -1380,58 +1380,6 @@ def decode_watermark(image:Image, watermark_image_size:int=94) -> Image:
|
||||
ret_image = normalize_gray(ret_image)
|
||||
return ret_image
|
||||
|
||||
# def generate_text_image(text:str, font_path:str, font_size:int, text_color:str="#FFFFFF",
|
||||
# vertical:bool=True, stroke_width:int=1, stroke_color:str="#000000",
|
||||
# spacing:int=0, leading:int=0) -> tuple:
|
||||
#
|
||||
# lines = text.split("\n")
|
||||
# if vertical:
|
||||
# layout = "vertical"
|
||||
# else:
|
||||
# layout = "horizontal"
|
||||
# char_coordinates = []
|
||||
# if layout == "vertical":
|
||||
# x = 0
|
||||
# y = 0
|
||||
# for i in range(len(lines)):
|
||||
# line = lines[i]
|
||||
# for char in line:
|
||||
# char_coordinates.append((x, y))
|
||||
# y += font_size + spacing
|
||||
# x += font_size + leading
|
||||
# y = 0
|
||||
# else:
|
||||
# x = 0
|
||||
# y = 0
|
||||
# for line in lines:
|
||||
# for char in line:
|
||||
# char_coordinates.append((x, y))
|
||||
# x += font_size + spacing
|
||||
# y += font_size + leading
|
||||
# x = 0
|
||||
# if layout == "vertical":
|
||||
# width = (len(lines) * (font_size + spacing)) - spacing
|
||||
# height = ((len(max(lines, key=len)) + 1) * (font_size + spacing)) + spacing
|
||||
# else:
|
||||
# width = (len(max(lines, key=len)) * (font_size + spacing)) - spacing
|
||||
# height = ((len(lines) - 1) * (font_size + spacing)) + font_size
|
||||
#
|
||||
# image = Image.new('RGBA', size=(width, height), color=stroke_color)
|
||||
# draw = ImageDraw.Draw(image)
|
||||
# font = ImageFont.truetype(font_path, font_size)
|
||||
# index = 0
|
||||
# for i, line in enumerate(lines):
|
||||
# for j, char in enumerate(line):
|
||||
# x, y = char_coordinates[index]
|
||||
# if stroke_width > 0:
|
||||
# draw.text((x - stroke_width, y), char, font=font, fill=stroke_color)
|
||||
# draw.text((x + stroke_width, y), char, font=font, fill=stroke_color)
|
||||
# draw.text((x, y - stroke_width), char, font=font, fill=stroke_color)
|
||||
# draw.text((x, y + stroke_width), char, font=font, fill=stroke_color)
|
||||
# draw.text((x, y), char, font=font, fill=text_color)
|
||||
# index += 1
|
||||
# return (image.convert('RGB'), image.split()[3])
|
||||
|
||||
def generate_text_image(width:int, height:int, text:str, font_file:str, text_scale:float=1, font_color:str="#FFFFFF",) -> Image:
|
||||
image = Image.new("RGBA", (width, height), (0, 0, 0, 0))
|
||||
draw = ImageDraw.Draw(image)
|
||||
@@ -1444,6 +1392,61 @@ def generate_text_image(width:int, height:int, text:str, font_file:str, text_sca
|
||||
draw.text((x, y), text, font=font, fill=font_color)
|
||||
return image
|
||||
|
||||
def displacement_image(image: Image, displacement_map: Image, strength: float, smoothness: int, anti_aliasing: int) -> Image:
|
||||
|
||||
if image.mode != 'RGB':
|
||||
image = image.convert('RGB')
|
||||
if displacement_map.mode != 'L':
|
||||
displacement_map = displacement_map.convert('L')
|
||||
|
||||
orig_w, orig_h = image.size
|
||||
|
||||
if displacement_map.size != image.size:
|
||||
displacement_map = displacement_map.resize(image.size, Image.LANCZOS)
|
||||
|
||||
if smoothness:
|
||||
displacement_map = gaussian_blur(displacement_map, smoothness)
|
||||
|
||||
if anti_aliasing > 1:
|
||||
up_size = (orig_w * anti_aliasing, orig_h * anti_aliasing)
|
||||
image = image.resize(up_size, Image.LANCZOS)
|
||||
displacement_map = displacement_map.resize(up_size, Image.LANCZOS)
|
||||
|
||||
img = np.asarray(image)
|
||||
disp = np.asarray(displacement_map).astype(np.float32)
|
||||
|
||||
h, w = disp.shape
|
||||
|
||||
ys, xs = np.meshgrid(
|
||||
np.arange(h, dtype=np.int32),
|
||||
np.arange(w, dtype=np.int32),
|
||||
indexing="ij"
|
||||
)
|
||||
|
||||
offset = (disp / 255.0 * strength * anti_aliasing).astype(np.int32)
|
||||
|
||||
new_x = xs + offset
|
||||
new_y = ys + offset
|
||||
|
||||
def mirror(coord, size):
|
||||
coord = np.where(coord < 0, -coord, coord)
|
||||
coord = np.where(coord >= size, 2 * size - coord - 1, coord)
|
||||
return coord
|
||||
|
||||
new_x = mirror(new_x, w)
|
||||
new_y = mirror(new_y, h)
|
||||
|
||||
out = img[new_y, new_x]
|
||||
|
||||
ret = Image.fromarray(out, mode="RGB")
|
||||
|
||||
if anti_aliasing > 1:
|
||||
ret = gaussian_blur(ret, int(anti_aliasing / 3))
|
||||
ret = ret.resize((orig_w, orig_h), Image.LANCZOS)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
'''Mask Functions'''
|
||||
|
||||
def create_mask_from_color_cv2(image:Image, color:str, tolerance:int=0) -> Image:
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "comfyui_layerstyle"
|
||||
description = "A set of nodes for ComfyUI it generate image like Adobe Photoshop's Layer Style. the Drop Shadow is first completed node, and follow-up work is in progress."
|
||||
version = "2.0.33"
|
||||
version = "2.0.34"
|
||||
license = {text = "MIT License"}
|
||||
dependencies = ["numpy", "pillow", "torch", "matplotlib", "Scipy", "scikit_image", "scikit_learn", "opencv-contrib-python", "pymatting", "timm", "colour-science", "transformers", "blend_modes", "huggingface_hub", "loguru"]
|
||||
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
{
|
||||
"id": "2faaee3f-fb4f-4675-bf73-0188eded5ad4",
|
||||
"revision": 0,
|
||||
"last_node_id": 43,
|
||||
"last_link_id": 90,
|
||||
"nodes": [
|
||||
{
|
||||
"id": 9,
|
||||
"type": "LoadImage",
|
||||
"pos": [
|
||||
-6656.189793454538,
|
||||
-1030.5373971645267
|
||||
],
|
||||
"size": [
|
||||
360.73952709359037,
|
||||
489.6573516743524
|
||||
],
|
||||
"flags": {},
|
||||
"order": 0,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
43,
|
||||
87
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "MASK",
|
||||
"type": "MASK",
|
||||
"links": null
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"cnr_id": "comfy-core",
|
||||
"ver": "0.6.0",
|
||||
"Node name for S&R": "LoadImage"
|
||||
},
|
||||
"widgets_values": [
|
||||
"768x1344_dress.png",
|
||||
"image"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"type": "LoadImage",
|
||||
"pos": [
|
||||
-6653.694433010127,
|
||||
-1579.8143566299393
|
||||
],
|
||||
"size": [
|
||||
352.59643720054373,
|
||||
490.82062740849506
|
||||
],
|
||||
"flags": {},
|
||||
"order": 1,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
88
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "MASK",
|
||||
"type": "MASK",
|
||||
"links": null
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"cnr_id": "comfy-core",
|
||||
"ver": "0.6.0",
|
||||
"Node name for S&R": "LoadImage"
|
||||
},
|
||||
"widgets_values": [
|
||||
"plaid.jpg",
|
||||
"image"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"type": "LayerMask: SegmentAnythingUltra V2",
|
||||
"pos": [
|
||||
-6120.023112208488,
|
||||
-1027.5182287606453
|
||||
],
|
||||
"size": [
|
||||
420.491796875,
|
||||
366
|
||||
],
|
||||
"flags": {},
|
||||
"order": 2,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "image",
|
||||
"type": "IMAGE",
|
||||
"link": 43
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "image",
|
||||
"type": "IMAGE",
|
||||
"links": null
|
||||
},
|
||||
{
|
||||
"name": "mask",
|
||||
"type": "MASK",
|
||||
"links": [
|
||||
89
|
||||
]
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"cnr_id": "ComfyUI_LayerStyle_Advance",
|
||||
"ver": "86cc56bbcffd9a3e61c0dc62c2eb857344c23fce",
|
||||
"Node name for S&R": "LayerMask: SegmentAnythingUltra V2"
|
||||
},
|
||||
"widgets_values": [
|
||||
"sam_vit_h (2.56GB)",
|
||||
"GroundingDINO_SwinT_OGC (694MB)",
|
||||
0.3,
|
||||
"VITMatte",
|
||||
6,
|
||||
6,
|
||||
0.15,
|
||||
0.99,
|
||||
true,
|
||||
"dress",
|
||||
"cuda",
|
||||
2,
|
||||
false
|
||||
],
|
||||
"color": "rgba(27, 80, 119, 0.7)"
|
||||
},
|
||||
{
|
||||
"id": 41,
|
||||
"type": "LayerFilter: DistortDisplace",
|
||||
"pos": [
|
||||
-5663.784182811386,
|
||||
-1392.847340659025
|
||||
],
|
||||
"size": [
|
||||
296.525390625,
|
||||
242
|
||||
],
|
||||
"flags": {},
|
||||
"order": 3,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "image",
|
||||
"type": "IMAGE",
|
||||
"link": 87
|
||||
},
|
||||
{
|
||||
"name": "material_image",
|
||||
"type": "IMAGE",
|
||||
"link": 88
|
||||
},
|
||||
{
|
||||
"name": "mask",
|
||||
"shape": 7,
|
||||
"type": "MASK",
|
||||
"link": 89
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "image",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
90
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "displaced_material",
|
||||
"type": "IMAGE",
|
||||
"links": null
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"cnr_id": "comfyui_layerstyle",
|
||||
"ver": "d256c3a0573d854f4eb382672397c3361cf12084",
|
||||
"Node name for S&R": "LayerFilter: DistortDisplace"
|
||||
},
|
||||
"widgets_values": [
|
||||
50,
|
||||
8,
|
||||
2,
|
||||
"linear burn",
|
||||
75,
|
||||
"screen",
|
||||
30
|
||||
],
|
||||
"color": "rgba(34, 67, 111, 0.7)"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"type": "PreviewImage",
|
||||
"pos": [
|
||||
-5218.693562230295,
|
||||
-1574.0943976697952
|
||||
],
|
||||
"size": [
|
||||
602.5899407651559,
|
||||
1000.8520524954201
|
||||
],
|
||||
"flags": {},
|
||||
"order": 4,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 90
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"properties": {
|
||||
"cnr_id": "comfy-core",
|
||||
"ver": "0.6.0",
|
||||
"Node name for S&R": "PreviewImage"
|
||||
},
|
||||
"widgets_values": []
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
[
|
||||
43,
|
||||
9,
|
||||
0,
|
||||
25,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
87,
|
||||
9,
|
||||
0,
|
||||
41,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
88,
|
||||
10,
|
||||
0,
|
||||
41,
|
||||
1,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
89,
|
||||
25,
|
||||
1,
|
||||
41,
|
||||
2,
|
||||
"MASK"
|
||||
],
|
||||
[
|
||||
90,
|
||||
41,
|
||||
0,
|
||||
22,
|
||||
0,
|
||||
"IMAGE"
|
||||
]
|
||||
],
|
||||
"groups": [],
|
||||
"config": {},
|
||||
"extra": {
|
||||
"ds": {
|
||||
"scale": 0.4305676431342591,
|
||||
"offset": [
|
||||
8224.326676621306,
|
||||
2659.4485264813743
|
||||
]
|
||||
},
|
||||
"frontendVersion": "1.35.9",
|
||||
"workflowRendererVersion": "LG",
|
||||
"VHS_latentpreview": false,
|
||||
"VHS_latentpreviewrate": 0,
|
||||
"VHS_MetadataImage": true,
|
||||
"VHS_KeepIntermediate": true
|
||||
},
|
||||
"version": 0.4
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 286 KiB |
Reference in New Issue
Block a user