first commit
This commit is contained in:
+384
@@ -0,0 +1,384 @@
|
||||
import numpy as np
|
||||
import torch
|
||||
from PIL import Image
|
||||
|
||||
# FrameMaker 0.1.0 by diSty
|
||||
|
||||
class FrameMaker:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
'required': {
|
||||
'subject_image': ('IMAGE',),
|
||||
'frame_count': ('INT', {'default': 4}),
|
||||
"invert_alpha": (['true','false'], {"default": 'false'}),
|
||||
"movement_presets": (movement,{"default": 'left to center',}),
|
||||
'movement_presets_distance': ('INT', {'default': 50, 'min': -10000, 'max': 10000}),
|
||||
"movement_direction": (['None','front', 'back'],{"default": 'back',}),
|
||||
'x_pos_start': ('INT', {'default': 0, 'min': -10000, 'max': 10000}),
|
||||
'x_pos_end': ('INT', {'default': 0, 'min': -10000, 'max': 10000}),
|
||||
'y_pos_start': ('INT', {'default': 0, 'min': -10000, 'max': 10000}),
|
||||
'y_pos_end': ('INT', {'default': 0, 'min': -10000, 'max': 10000}),
|
||||
'scale_start': ('FLOAT', {'default': 1, 'min': 0.05, 'step': 0.05, 'max': 10}),
|
||||
'scale_end': ('FLOAT', {'default': 1, 'min': 0.05, 'step': 0.05, 'max': 10}),
|
||||
"scale_anchor_point": (['center','top center', 'bottom center', 'top left', 'top right', 'bottom left', 'bottom right'],),
|
||||
},
|
||||
"optional": {
|
||||
"subject_alpha": ("MASK",),
|
||||
'bg1': ('IMAGE',),
|
||||
'bg2': ('IMAGE',),
|
||||
'bg3': ('IMAGE',),
|
||||
'bg4': ('IMAGE',),
|
||||
'frames': ('IMAGE',),
|
||||
"resize_frame_input": (['true','false'], {"default": 'true'}),
|
||||
'frame_input_width': ('INT', {'default': 768, 'min': 16,'step': 16, 'max': 8192}),
|
||||
'frame_input_height': ('INT', {'default': 768, 'min': 16,'step': 16, 'max': 8192}),
|
||||
"resize_frame_output": (['true','false'], {"default": 'false'}),
|
||||
'frame_output_width': ('INT', {'default': 512, 'min': 16,'step': 16, 'max': 8192}),
|
||||
'frame_output_height': ('INT', {'default': 512, 'min': 16,'step': 16, 'max': 8192}),
|
||||
"invert_order": (['true','false'], {"default": 'false'}),
|
||||
# "limit_frames": (['true','false'], {"default": 'false'}),
|
||||
# 'limit_frames_count': ('INT', {'default': 4, 'min': 1,'step': 1, 'max': 10000}),
|
||||
# 'limit_frames_index': ('INT', {'default': 1, 'min': 1,'step': 1, 'max': 10000}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ('IMAGE','IMAGE','INT', 'INT', 'INT',)
|
||||
RETURN_NAMES = ('frames','subject_image', 'width', 'height','frame_count',)
|
||||
FUNCTION = 'process_frames'
|
||||
CATEGORY = '🅓 diSty/FrameMaker'
|
||||
|
||||
def process_frames(self, subject_image, frame_count,invert_alpha,movement_presets,movement_presets_distance,movement_direction,
|
||||
x_pos_start, x_pos_end, y_pos_start, y_pos_end, scale_start, scale_end, scale_anchor_point,
|
||||
subject_alpha=None,bg1=None, bg2=None, bg3=None, bg4=None,frames=None,width=0, height=0,resize_frame_input=0, frame_input_width=0,
|
||||
frame_input_height=0,resize_frame_output=None, frame_output_width=0,frame_output_height=0,invert_order='false'
|
||||
# , **kwargs
|
||||
):
|
||||
|
||||
if subject_alpha is not None:
|
||||
if invert_alpha == 'true':
|
||||
subject_alpha = 1.0 - subject_alpha
|
||||
subject_image = join_image_with_alpha(subject_image, subject_alpha)
|
||||
|
||||
foreground_image_pil = tensor2pil(subject_image)
|
||||
backgrounds = [bg1, bg2, bg3, bg4]
|
||||
backgrounds = [b for b in backgrounds if b is not None]
|
||||
|
||||
if frames is not None:
|
||||
backgrounds = []
|
||||
for i in range(frames.shape[0]):
|
||||
frame_tensor = frames[i]
|
||||
backgrounds.append(frame_tensor)
|
||||
|
||||
if resize_frame_input == 'true':
|
||||
foreground_image_pil = foreground_image_pil.resize((frame_input_width, frame_input_height), Image.Resampling.LANCZOS)
|
||||
width = frame_input_width
|
||||
height = frame_input_height
|
||||
|
||||
resized_backgrounds_pil = []
|
||||
for bg_tensor in backgrounds:
|
||||
bg_pil = tensor2pil(bg_tensor)
|
||||
resized_bg_pil = bg_pil.resize((frame_input_width, frame_input_height), Image.Resampling.LANCZOS)
|
||||
resized_backgrounds_pil.append(resized_bg_pil)
|
||||
|
||||
movement_map = movement_map_f(movement_presets_distance)
|
||||
|
||||
if movement_presets != 'None' and movement_presets in movement_map:
|
||||
preset = movement_map[movement_presets]
|
||||
x_pos_start = preset['x_start']
|
||||
x_pos_end = preset['x_end']
|
||||
y_pos_start = preset['y_start']
|
||||
y_pos_end = preset['y_end']
|
||||
|
||||
x_pos_start_pix = x_pos_start * foreground_image_pil.width / 100
|
||||
x_pos_end_pix = x_pos_end * foreground_image_pil.width / 100
|
||||
y_pos_start_pix = y_pos_start * foreground_image_pil.height / 100
|
||||
y_pos_end_pix = y_pos_end * foreground_image_pil.height / 100
|
||||
|
||||
if movement_direction != 'None':
|
||||
if movement_direction == 'front':
|
||||
scale_start = .3
|
||||
scale_end = 1.3
|
||||
if movement_direction == 'back':
|
||||
scale_start = 1.3
|
||||
scale_end = .3
|
||||
|
||||
x_step = (x_pos_end_pix - x_pos_start_pix) / (frame_count - 1)
|
||||
y_step = (y_pos_end_pix - y_pos_start_pix) / (frame_count - 1)
|
||||
scale_step = (scale_end - scale_start) / (frame_count - 1)
|
||||
|
||||
result_images = []
|
||||
for frame in range(frame_count):
|
||||
if resize_frame_input == 'true':
|
||||
background_image_pil = resized_backgrounds_pil[frame % len(resized_backgrounds_pil)]
|
||||
else:
|
||||
background_image_pil = tensor2pil(backgrounds[frame % len(backgrounds)])
|
||||
|
||||
scale = scale_start + frame * scale_step
|
||||
scaled_width = int(foreground_image_pil.width * scale)
|
||||
scaled_height = int(foreground_image_pil.height * scale)
|
||||
|
||||
foreground_resized = foreground_image_pil.resize((scaled_width, scaled_height), Image.Resampling.LANCZOS)
|
||||
|
||||
x_pos = x_pos_start_pix + frame * x_step
|
||||
y_pos = y_pos_start_pix + frame * y_step
|
||||
|
||||
width_diff = (scaled_width - foreground_image_pil.width)
|
||||
height_diff = (scaled_height - foreground_image_pil.height)
|
||||
|
||||
if 'center' in scale_anchor_point.lower():
|
||||
x_pos -= width_diff // 2
|
||||
if scale_anchor_point.lower() == 'center':
|
||||
y_pos -= height_diff // 2
|
||||
elif 'bottom' in scale_anchor_point.lower():
|
||||
y_pos -= height_diff
|
||||
if 'right' in scale_anchor_point.lower():
|
||||
x_pos -= width_diff
|
||||
frame_image = background_image_pil.copy()
|
||||
if foreground_resized.mode != 'RGBA':
|
||||
foreground_resized = foreground_resized.convert('RGBA')
|
||||
|
||||
frame_image.paste(foreground_resized, (int(x_pos), int(y_pos)), foreground_resized)
|
||||
|
||||
if resize_frame_output == 'true':
|
||||
frame_image = frame_image.resize((frame_output_width, frame_output_height), Image.Resampling.LANCZOS)
|
||||
width = frame_output_width
|
||||
height = frame_output_height
|
||||
result_images.append(pil2tensor(frame_image))
|
||||
|
||||
batch = torch.cat(result_images, dim=0)
|
||||
if invert_order == 'true':
|
||||
batch = batch.flip(dims=[0])
|
||||
|
||||
return (batch,) + (subject_image,) + (width,) + (height,) + (frame_count,)
|
||||
|
||||
class FrameMakerBatch:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
'required': {
|
||||
'frames': ('IMAGE',),
|
||||
'subject_image': ('IMAGE',),
|
||||
'frame_count': ('INT', {'default': 4}),
|
||||
"invert_alpha": (['true','false'], {"default": 'false'}),
|
||||
"movement_presets": (movement,{"default": 'left to center',}),
|
||||
'movement_presets_distance': ('INT', {'default': 50, 'min': -10000, 'max': 10000}),
|
||||
"movement_direction": (['None','front', 'back'],{"default": 'back',}),
|
||||
'x_pos_start': ('INT', {'default': 0, 'min': -10000, 'max': 10000}),
|
||||
'x_pos_end': ('INT', {'default': 0, 'min': -10000, 'max': 10000}),
|
||||
'y_pos_start': ('INT', {'default': 0, 'min': -10000, 'max': 10000}),
|
||||
'y_pos_end': ('INT', {'default': 0, 'min': -10000, 'max': 10000}),
|
||||
'scale_start': ('FLOAT', {'default': 1, 'min': 0.05, 'step': 0.05, 'max': 10}),
|
||||
'scale_end': ('FLOAT', {'default': 1, 'min': 0.05, 'step': 0.05, 'max': 10}),
|
||||
"scale_anchor_point": (['center','top center', 'bottom center', 'top left', 'top right', 'bottom left', 'bottom right'],),
|
||||
},
|
||||
"optional": {
|
||||
"subject_alpha": ("MASK",),
|
||||
"resize_frame_input": (['true','false'], {"default": 'true'}),
|
||||
'frame_input_width': ('INT', {'default': 768, 'min': 16,'step': 16, 'max': 8192}),
|
||||
'frame_input_height': ('INT', {'default': 768, 'min': 16,'step': 16, 'max': 8192}),
|
||||
"resize_frame_output": (['true','false'], {"default": 'false'}),
|
||||
'frame_output_width': ('INT', {'default': 512, 'min': 16,'step': 16, 'max': 8192}),
|
||||
'frame_output_height': ('INT', {'default': 512, 'min': 16,'step': 16, 'max': 8192}),
|
||||
"invert_order": (['true','false'], {"default": 'false'}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ('IMAGE','IMAGE','INT', 'INT', 'INT',)
|
||||
RETURN_NAMES = ('frames','subject_image', 'width', 'height','frame_count',)
|
||||
FUNCTION = 'process_frames'
|
||||
CATEGORY = '🅓 diSty/FrameMaker'
|
||||
|
||||
def process_frames(self,frames,subject_image, frame_count,invert_alpha,movement_presets,movement_presets_distance,movement_direction,
|
||||
x_pos_start, x_pos_end, y_pos_start, y_pos_end, scale_start, scale_end, scale_anchor_point,
|
||||
subject_alpha=None,width=0, height=0,resize_frame_input=0, frame_input_width=0,
|
||||
frame_input_height=0,resize_frame_output=None, frame_output_width=0,frame_output_height=0,invert_order='false'):
|
||||
|
||||
|
||||
if subject_alpha is not None:
|
||||
if invert_alpha == 'true':
|
||||
subject_alpha = 1.0 - subject_alpha
|
||||
subject_image = join_image_with_alpha(subject_image, subject_alpha)
|
||||
|
||||
foreground_image_pil = tensor2pil(subject_image)
|
||||
|
||||
if frames is not None:
|
||||
backgrounds = []
|
||||
for i in range(frames.shape[0]):
|
||||
frame_tensor = frames[i]
|
||||
backgrounds.append(frame_tensor)
|
||||
|
||||
if resize_frame_input == 'true':
|
||||
foreground_image_pil = foreground_image_pil.resize((frame_input_width, frame_input_height), Image.Resampling.LANCZOS)
|
||||
width = frame_input_width
|
||||
height = frame_input_height
|
||||
|
||||
resized_backgrounds_pil = []
|
||||
for bg_tensor in backgrounds:
|
||||
bg_pil = tensor2pil(bg_tensor)
|
||||
resized_bg_pil = bg_pil.resize((frame_input_width, frame_input_height), Image.Resampling.LANCZOS)
|
||||
resized_backgrounds_pil.append(resized_bg_pil)
|
||||
|
||||
movement_map = movement_map_f(movement_presets_distance)
|
||||
|
||||
if movement_presets != 'None' and movement_presets in movement_map:
|
||||
preset = movement_map[movement_presets]
|
||||
x_pos_start = preset['x_start']
|
||||
x_pos_end = preset['x_end']
|
||||
y_pos_start = preset['y_start']
|
||||
y_pos_end = preset['y_end']
|
||||
|
||||
|
||||
x_pos_start_pix = x_pos_start * foreground_image_pil.width / 100
|
||||
x_pos_end_pix = x_pos_end * foreground_image_pil.width / 100
|
||||
y_pos_start_pix = y_pos_start * foreground_image_pil.height / 100
|
||||
y_pos_end_pix = y_pos_end * foreground_image_pil.height / 100
|
||||
|
||||
if movement_direction != 'None':
|
||||
if movement_direction == 'front':
|
||||
scale_start = .3
|
||||
scale_end = 1.3
|
||||
if movement_direction == 'back':
|
||||
scale_start = 1.3
|
||||
scale_end = .3
|
||||
|
||||
x_step = (x_pos_end_pix - x_pos_start_pix) / (frame_count - 1)
|
||||
y_step = (y_pos_end_pix - y_pos_start_pix) / (frame_count - 1)
|
||||
scale_step = (scale_end - scale_start) / (frame_count - 1)
|
||||
|
||||
result_images = []
|
||||
for frame in range(frame_count):
|
||||
if resize_frame_input == 'true':
|
||||
background_image_pil = resized_backgrounds_pil[frame % len(resized_backgrounds_pil)]
|
||||
else:
|
||||
background_image_pil = tensor2pil(backgrounds[frame % len(backgrounds)])
|
||||
|
||||
scale = scale_start + frame * scale_step
|
||||
scaled_width = int(foreground_image_pil.width * scale)
|
||||
scaled_height = int(foreground_image_pil.height * scale)
|
||||
|
||||
foreground_resized = foreground_image_pil.resize((scaled_width, scaled_height), Image.Resampling.LANCZOS)
|
||||
|
||||
x_pos = x_pos_start_pix + frame * x_step
|
||||
y_pos = y_pos_start_pix + frame * y_step
|
||||
|
||||
width_diff = (scaled_width - foreground_image_pil.width)
|
||||
height_diff = (scaled_height - foreground_image_pil.height)
|
||||
|
||||
if 'center' in scale_anchor_point.lower():
|
||||
x_pos -= width_diff // 2
|
||||
|
||||
if scale_anchor_point.lower() == 'center':
|
||||
y_pos -= height_diff // 2
|
||||
elif 'bottom' in scale_anchor_point.lower():
|
||||
y_pos -= height_diff
|
||||
if 'right' in scale_anchor_point.lower():
|
||||
x_pos -= width_diff
|
||||
frame_image = background_image_pil.copy()
|
||||
if foreground_resized.mode != 'RGBA':
|
||||
foreground_resized = foreground_resized.convert('RGBA')
|
||||
|
||||
frame_image.paste(foreground_resized, (int(x_pos), int(y_pos)), foreground_resized)
|
||||
|
||||
if resize_frame_output == 'true':
|
||||
frame_image = frame_image.resize((frame_output_width, frame_output_height), Image.Resampling.LANCZOS)
|
||||
width = frame_output_width
|
||||
height = frame_output_height
|
||||
result_images.append(pil2tensor(frame_image))
|
||||
|
||||
batch = torch.cat(result_images, dim=0)
|
||||
if invert_order == 'true':
|
||||
batch = batch.flip(dims=[0])
|
||||
|
||||
return (batch,) + (subject_image,) + (width,) + (height,) + (frame_count,)
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"FrameMaker": FrameMaker,
|
||||
"FrameMakerBatch": FrameMakerBatch
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"FrameMaker": f"🅓 Frame Maker ",
|
||||
"FrameMakerBatch": f"🅓 Frame Maker Batch"
|
||||
}
|
||||
|
||||
def tensor2pil(image):
|
||||
return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
|
||||
|
||||
def pil2tensor(image):
|
||||
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
|
||||
|
||||
def resize_mask(mask, shape):
|
||||
return torch.nn.functional.interpolate(mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])), size=(shape[0], shape[1]), mode="bilinear").squeeze(1)
|
||||
|
||||
def join_image_with_alpha(image: torch.Tensor, alpha: torch.Tensor):
|
||||
batch_size = min(len(image), len(alpha))
|
||||
out_images = []
|
||||
|
||||
alpha = 1.0 - resize_mask(alpha, image.shape[1:])
|
||||
for i in range(batch_size):
|
||||
out_images.append(torch.cat((image[i][:,:,:3], alpha[i].unsqueeze(2)), dim=2))
|
||||
|
||||
result = (torch.stack(out_images))
|
||||
return result
|
||||
|
||||
def movement_map_f(movement_presets_distance):
|
||||
movement_map = {
|
||||
'left to center': {'x_start': -movement_presets_distance, 'x_end': 0, 'y_start': 0, 'y_end': 0},
|
||||
'right to center': {'x_start': movement_presets_distance, 'x_end': 0, 'y_start': 0, 'y_end': 0},
|
||||
'center to left': {'x_start': 0, 'x_end': -movement_presets_distance, 'y_start': 0, 'y_end': 0},
|
||||
'center to right': {'x_start': 0, 'x_end': movement_presets_distance, 'y_start': 0, 'y_end': 0},
|
||||
'left to right': {'x_start': -movement_presets_distance, 'x_end': movement_presets_distance, 'y_start': 0, 'y_end': 0},
|
||||
'right to left': {'x_start': movement_presets_distance, 'x_end': -movement_presets_distance, 'y_start': 0, 'y_end': 0},
|
||||
'top to center': {'x_start': 0, 'x_end': 0, 'y_start': -movement_presets_distance, 'y_end': 0},
|
||||
'bottom to center': {'x_start': 0, 'x_end': 0, 'y_start': movement_presets_distance, 'y_end': 0},
|
||||
'center to top': {'x_start': 0, 'x_end': 0, 'y_start': 0, 'y_end': -movement_presets_distance},
|
||||
'center to bottom': {'x_start': 0, 'x_end': 0, 'y_start': 0, 'y_end': movement_presets_distance},
|
||||
'top to bottom': {'x_start': 0, 'x_end': 0, 'y_start': -movement_presets_distance, 'y_end': movement_presets_distance},
|
||||
'bottom to top': {'x_start': 0, 'x_end': 0, 'y_start': movement_presets_distance, 'y_end': -movement_presets_distance},
|
||||
'top left to center': {'x_start': -movement_presets_distance, 'x_end': 0, 'y_start': -movement_presets_distance, 'y_end': 0},
|
||||
'top right to center': {'x_start': movement_presets_distance, 'x_end': 0, 'y_start': -movement_presets_distance, 'y_end': 0},
|
||||
'bottom left to center': {'x_start': -movement_presets_distance, 'x_end': 0, 'y_start': movement_presets_distance, 'y_end': 0},
|
||||
'bottom right to center': {'x_start': movement_presets_distance, 'x_end': 0, 'y_start': movement_presets_distance, 'y_end': 0},
|
||||
'center to top left': {'x_start': 0, 'x_end': -movement_presets_distance, 'y_start': 0, 'y_end': -movement_presets_distance},
|
||||
'center to top right': {'x_start': 0, 'x_end': movement_presets_distance, 'y_start': 0, 'y_end': -movement_presets_distance},
|
||||
'center to bottom left': {'x_start': 0, 'x_end': -movement_presets_distance, 'y_start': 0, 'y_end': movement_presets_distance},
|
||||
'center to bottom right': {'x_start': 0, 'x_end': movement_presets_distance, 'y_start': 0, 'y_end': movement_presets_distance},
|
||||
'top left to bottom right': {'x_start': -movement_presets_distance, 'x_end': movement_presets_distance, 'y_start': -movement_presets_distance, 'y_end': movement_presets_distance},
|
||||
'bottom right to top left': {'x_start': movement_presets_distance, 'x_end': -movement_presets_distance, 'y_start': movement_presets_distance, 'y_end': -movement_presets_distance},
|
||||
'top right to bottom left': {'x_start': movement_presets_distance, 'x_end': -movement_presets_distance, 'y_start': -movement_presets_distance, 'y_end': movement_presets_distance},
|
||||
'bottom left to top right': {'x_start': -movement_presets_distance, 'x_end': movement_presets_distance, 'y_start': movement_presets_distance, 'y_end': -movement_presets_distance},
|
||||
}
|
||||
|
||||
return movement_map
|
||||
|
||||
movement = ['None',
|
||||
'left to center',
|
||||
'right to center',
|
||||
'center to left',
|
||||
'center to right',
|
||||
'left to right',
|
||||
'right to left',
|
||||
|
||||
'top to center',
|
||||
'bottom to center',
|
||||
'top to bottom',
|
||||
'bottom to top',
|
||||
'center to top',
|
||||
'center to bottom',
|
||||
|
||||
'top left to center',
|
||||
'top right to center',
|
||||
'bottom left to center',
|
||||
'bottom right to center',
|
||||
|
||||
'center to top left',
|
||||
'center to top right',
|
||||
'center to bottom left',
|
||||
'center to bottom right',
|
||||
|
||||
'top left to bottom right',
|
||||
'bottom right to top left',
|
||||
'top right to bottom left',
|
||||
'bottom left to top right'
|
||||
]
|
||||
@@ -0,0 +1,158 @@
|
||||
<!-- Improved compatibility of back to top link: See: https://github.com/othneildrew/Best-README-Template/pull/73 -->
|
||||
<a name="readme-top"></a>
|
||||
<!--
|
||||
*** Thanks for checking out the Best-README-Template. If you have a suggestion
|
||||
*** that would make this better, please fork the repo and create a pull request
|
||||
*** or simply open an issue with the tag "enhancement".
|
||||
*** Don't forget to give the project a star!
|
||||
*** Thanks again! Now go create something AMAZING! :D
|
||||
-->
|
||||
<!--
|
||||
*** I'm using markdown "reference style" links for readability.
|
||||
*** Reference links are enclosed in brackets [ ] instead of parentheses ( ).
|
||||
*** See the bottom of this document for the declaration of the reference variables
|
||||
*** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use.
|
||||
*** https://www.markdownguide.org/basic-syntax/#reference-style-links
|
||||
-->
|
||||
<br />
|
||||
<div align="center">
|
||||
|
||||
[](https://www.patreon.com/distyx)
|
||||
|
||||
<!-- <img src="media/covers/cover.jpg"> -->
|
||||
|
||||
<h1 align="center">ComfyUI Frame Maker</h1>
|
||||
<h4 align="center"><em>Add control and cool effects into your animation.</em></h4>
|
||||
<h4 align="center">Don't forget to leave a star.</h4>
|
||||
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/diStyApps/ComfyUI_FrameMaker/issues">Report Bug</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- TABLE OF CONTENTS -->
|
||||
<details>
|
||||
<summary>Table of Contents</summary>
|
||||
<ol>
|
||||
<li>
|
||||
<a href="#about-the-project">About The Project</a>
|
||||
</li>
|
||||
<li><a href="#requirements">Requirements</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li><a href="#my-other-projects">My Other Projects</a></li>
|
||||
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
<!-- ABOUT THE PROJECT -->
|
||||
## About The Project
|
||||
|
||||
### This node creates a sequence of frames by moving and scaling a subject image over a background image.
|
||||
|
||||
|
||||
## <a href="workflows/frame_maker_basic.json">Basic frame maker workflow</a>
|
||||
|
||||
<img src="workflows/frame_maker_basic.png">
|
||||
|
||||
## <a href="workflows/frame_maker_batch">Basic batch frame maker workflow</a>
|
||||
|
||||
<img src="media/preview/frame_maker_1.gif">
|
||||
|
||||
## <a href="workflows/frame_maker_basic.json">layerdiffusion frame maker workflow</a>
|
||||
|
||||
<img src="media/preview/frame_maker_2.gif">
|
||||
|
||||
## frame maker + splash workflow (soon)
|
||||
|
||||
<img src="media/preview/frame_maker_3.gif">
|
||||
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
<!-- Requirements -->
|
||||
## Requirements
|
||||
- [CompfyUI](https://github.com/comfyanonymous/ComfyUI)
|
||||
|
||||
### Recommended
|
||||
- [ComfyUI-Manager](https://github.com/ltdrdata/ComfyUI-Manager)
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
|
||||
|
||||
<!-- Requirements -->
|
||||
## Install
|
||||
|
||||
```
|
||||
cd custom_nodes
|
||||
git clone https://github.com/diStyApps/ComfyUI_FrameMaker.git
|
||||
```
|
||||
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
|
||||
<!-- CONTACT -->
|
||||
## Contact
|
||||
|
||||
distty@gmail.com
|
||||
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
<!-- MY OTHER PROJECTS -->
|
||||
## My Other Projects
|
||||
|
||||
[SEAIT](https://github.com/diStyApps/seait)
|
||||
|
||||
[VisionCrafter](https://github.com/diStyApps/VisionCrafter)
|
||||
|
||||
[FaceSwapSuite](https://github.com/diStyApps/FaceSwapSuite)
|
||||
|
||||
[VisualClipPicker](https://github.com/diStyApps/VisualClipPicker)
|
||||
|
||||
[Stable-Diffusion-Pickle-Scanner-GUI](https://github.com/diStyApps/Stable-Diffusion-Pickle-Scanner-GUI)
|
||||
|
||||
[Safe-and-Stable-Ckpt2Safetensors-Conversion-Tool-GUI](https://github.com/diStyApps/Safe-and-Stable-Ckpt2Safetensors-Conversion-Tool-GUI)
|
||||
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
|
||||
<!-- MARKDOWN LINKS & IMAGES -->
|
||||
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
|
||||
[contributors-shield]: https://img.shields.io/github/contributors/othneildrew/Best-README-Template.svg?style=for-the-badge
|
||||
[contributors-url]: https://github.com/othneildrew/Best-README-Template/graphs/contributors
|
||||
[forks-shield]: https://img.shields.io/github/forks/othneildrew/Best-README-Template.svg?style=for-the-badge
|
||||
[forks-url]: https://github.com/othneildrew/Best-README-Template/network/members
|
||||
[stars-shield]: https://img.shields.io/github/stars/othneildrew/Best-README-Template.svg?style=for-the-badge
|
||||
[stars-url]: https://github.com/othneildrew/Best-README-Template/stargazers
|
||||
[issues-shield]: https://img.shields.io/github/issues/othneildrew/Best-README-Template.svg?style=for-the-badge
|
||||
[issues-url]: https://github.com/othneildrew/Best-README-Template/issues
|
||||
[license-shield]: https://img.shields.io/github/license/othneildrew/Best-README-Template.svg?style=for-the-badge
|
||||
[license-url]: https://github.com/othneildrew/Best-README-Template/blob/master/LICENSE.txt
|
||||
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
|
||||
[linkedin-url]: https://linkedin.com/in/othneildrew
|
||||
[product-screenshot]: images/screenshot.png
|
||||
[Next.js]: https://img.shields.io/badge/next.js-000000?style=for-the-badge&logo=nextdotjs&logoColor=white
|
||||
[Next-url]: https://nextjs.org/
|
||||
[React.js]: https://img.shields.io/badge/React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB
|
||||
[React-url]: https://reactjs.org/
|
||||
[Vue.js]: https://img.shields.io/badge/Vue.js-35495E?style=for-the-badge&logo=vuedotjs&logoColor=4FC08D
|
||||
[Vue-url]: https://vuejs.org/
|
||||
[Angular.io]: https://img.shields.io/badge/Angular-DD0031?style=for-the-badge&logo=angular&logoColor=white
|
||||
[Angular-url]: https://angular.io/
|
||||
[Svelte.dev]: https://img.shields.io/badge/Svelte-4A4A55?style=for-the-badge&logo=svelte&logoColor=FF3E00
|
||||
[Svelte-url]: https://svelte.dev/
|
||||
[Laravel.com]: https://img.shields.io/badge/Laravel-FF2D20?style=for-the-badge&logo=laravel&logoColor=white
|
||||
[Laravel-url]: https://laravel.com
|
||||
[Bootstrap.com]: https://img.shields.io/badge/Bootstrap-563D7C?style=for-the-badge&logo=bootstrap&logoColor=white
|
||||
[Bootstrap-url]: https://getbootstrap.com
|
||||
[JQuery.com]: https://img.shields.io/badge/jQuery-0769AD?style=for-the-badge&logo=jquery&logoColor=white
|
||||
[JQuery-url]: https://jquery.com
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
from .FrameMaker import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
|
||||
WEB_DIRECTORY = "js"
|
||||
|
||||
CC_VERSION = 2.0
|
||||
|
||||
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', 'CC_VERSION']
|
||||
@@ -0,0 +1,66 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
|
||||
const COLOR_THEMES = {
|
||||
red: { nodeColor: "#332222", nodeBgColor: "#553333" },
|
||||
green: { nodeColor: "#223322", nodeBgColor: "#335533" },
|
||||
blue: { nodeColor: "#222233", nodeBgColor: "#333355" },
|
||||
pale_blue: { nodeColor: "#2a363b", nodeBgColor: "#3f5159" },
|
||||
cyan: { nodeColor: "#223333", nodeBgColor: "#335555" },
|
||||
purple: { nodeColor: "#332233", nodeBgColor: "#553355" },
|
||||
yellow: { nodeColor: "#443322", nodeBgColor: "#665533" },
|
||||
// purple_custom: { nodeColor: "#7345b0" , nodeBgColor: "#482b6e" },
|
||||
purple_custom: { nodeColor: "#111111" , nodeBgColor: "#482b6e" },
|
||||
|
||||
none: { nodeColor: null, nodeBgColor: null } // no color
|
||||
};
|
||||
|
||||
const NODE_COLORS = {
|
||||
"FrameMaker": "purple_custom",
|
||||
"FrameMakerBatch": "purple_custom",
|
||||
|
||||
|
||||
};
|
||||
|
||||
function shuffleArray(array) {
|
||||
for (let i = array.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[array[i], array[j]] = [array[j], array[i]]; // Swap elements
|
||||
}
|
||||
}
|
||||
|
||||
let colorKeys = Object.keys(COLOR_THEMES).filter(key => key !== "none");
|
||||
shuffleArray(colorKeys); // Shuffle the color themes initially
|
||||
|
||||
function setNodeColors(node, theme) {
|
||||
if (!theme) {return;}
|
||||
node.shape = "box";
|
||||
if(theme.nodeColor && theme.nodeBgColor) {
|
||||
node.color = theme.nodeColor;
|
||||
node.bgcolor = theme.nodeBgColor;
|
||||
}
|
||||
}
|
||||
|
||||
const ext = {
|
||||
name: "disty.appearance",
|
||||
|
||||
nodeCreated(node) {
|
||||
const nclass = node.comfyClass;
|
||||
if (NODE_COLORS.hasOwnProperty(nclass)) {
|
||||
let colorKey = NODE_COLORS[nclass];
|
||||
|
||||
if (colorKey === "random") {
|
||||
// Check for a valid color key before popping
|
||||
if (colorKeys.length === 0 || !COLOR_THEMES[colorKeys[colorKeys.length - 1]]) {
|
||||
colorKeys = Object.keys(COLOR_THEMES).filter(key => key !== "none");
|
||||
shuffleArray(colorKeys);
|
||||
}
|
||||
colorKey = colorKeys.pop();
|
||||
}
|
||||
|
||||
const theme = COLOR_THEMES[colorKey];
|
||||
setNodeColors(node, theme);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
app.registerExtension(ext);
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.4 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.6 MiB |
@@ -0,0 +1,271 @@
|
||||
{
|
||||
"last_node_id": 16,
|
||||
"last_link_id": 28,
|
||||
"nodes": [
|
||||
{
|
||||
"id": 2,
|
||||
"type": "LoadImage",
|
||||
"pos": [
|
||||
120,
|
||||
70
|
||||
],
|
||||
"size": [
|
||||
240,
|
||||
310
|
||||
],
|
||||
"flags": {},
|
||||
"order": 0,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
1
|
||||
],
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "MASK",
|
||||
"type": "MASK",
|
||||
"links": [
|
||||
2
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "LoadImage"
|
||||
},
|
||||
"widgets_values": [
|
||||
"ComfyUI_13306_.png",
|
||||
"image"
|
||||
],
|
||||
"shape": 1
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"type": "LoadImage",
|
||||
"pos": [
|
||||
110,
|
||||
430
|
||||
],
|
||||
"size": {
|
||||
"0": 250,
|
||||
"1": 350
|
||||
},
|
||||
"flags": {},
|
||||
"order": 1,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
4
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "MASK",
|
||||
"type": "MASK",
|
||||
"links": [],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "LoadImage"
|
||||
},
|
||||
"widgets_values": [
|
||||
"gm_forest_00008_.png",
|
||||
"image"
|
||||
],
|
||||
"shape": 1
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"type": "FrameMaker",
|
||||
"pos": [
|
||||
400,
|
||||
70
|
||||
],
|
||||
"size": {
|
||||
"0": 342.5999755859375,
|
||||
"1": 610
|
||||
},
|
||||
"flags": {},
|
||||
"order": 2,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "subject_image",
|
||||
"type": "IMAGE",
|
||||
"link": 1,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "subject_alpha",
|
||||
"type": "MASK",
|
||||
"link": 2
|
||||
},
|
||||
{
|
||||
"name": "bg1",
|
||||
"type": "IMAGE",
|
||||
"link": 4,
|
||||
"slot_index": 2
|
||||
},
|
||||
{
|
||||
"name": "bg2",
|
||||
"type": "IMAGE",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "bg3",
|
||||
"type": "IMAGE",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "bg4",
|
||||
"type": "IMAGE",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "frames",
|
||||
"type": "IMAGE",
|
||||
"link": null
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "frames",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
28
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "subject_image",
|
||||
"type": "IMAGE",
|
||||
"links": [],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
},
|
||||
{
|
||||
"name": "width",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "height",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "frame_count",
|
||||
"type": "INT",
|
||||
"links": [],
|
||||
"shape": 3,
|
||||
"slot_index": 4
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "FrameMaker"
|
||||
},
|
||||
"widgets_values": [
|
||||
4,
|
||||
"false",
|
||||
"center to right",
|
||||
50,
|
||||
"front",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
"center",
|
||||
"true",
|
||||
768,
|
||||
768,
|
||||
"false",
|
||||
512,
|
||||
512,
|
||||
"false"
|
||||
],
|
||||
"color": "#111111",
|
||||
"bgcolor": "#482b6e",
|
||||
"shape": 1
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"type": "PreviewImage",
|
||||
"pos": [
|
||||
780,
|
||||
70
|
||||
],
|
||||
"size": {
|
||||
"0": 590,
|
||||
"1": 610
|
||||
},
|
||||
"flags": {},
|
||||
"order": 3,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 28
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "PreviewImage"
|
||||
},
|
||||
"shape": 1
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
[
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
"MASK"
|
||||
],
|
||||
[
|
||||
4,
|
||||
4,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
28,
|
||||
1,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
"IMAGE"
|
||||
]
|
||||
],
|
||||
"groups": [],
|
||||
"config": {},
|
||||
"extra": {},
|
||||
"version": 0.4
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 577 KiB |
@@ -0,0 +1,768 @@
|
||||
{
|
||||
"last_node_id": 15,
|
||||
"last_link_id": 27,
|
||||
"nodes": [
|
||||
{
|
||||
"id": 2,
|
||||
"type": "LoadImage",
|
||||
"pos": [
|
||||
20,
|
||||
60
|
||||
],
|
||||
"size": [
|
||||
320,
|
||||
310
|
||||
],
|
||||
"flags": {},
|
||||
"order": 0,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
1
|
||||
],
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "MASK",
|
||||
"type": "MASK",
|
||||
"links": [
|
||||
2
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "LoadImage"
|
||||
},
|
||||
"widgets_values": [
|
||||
"ComfyUI_13306_.png",
|
||||
"image"
|
||||
],
|
||||
"shape": 1
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"type": "FrameMakerBatch",
|
||||
"pos": [
|
||||
740,
|
||||
70
|
||||
],
|
||||
"size": [
|
||||
350,
|
||||
590
|
||||
],
|
||||
"flags": {},
|
||||
"order": 3,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "frames",
|
||||
"type": "IMAGE",
|
||||
"link": 8,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "subject_image",
|
||||
"type": "IMAGE",
|
||||
"link": 9
|
||||
},
|
||||
{
|
||||
"name": "subject_alpha",
|
||||
"type": "MASK",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "frame_count",
|
||||
"type": "INT",
|
||||
"link": 11,
|
||||
"widget": {
|
||||
"name": "frame_count"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "frames",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
15
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "subject_image",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
16
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
},
|
||||
{
|
||||
"name": "width",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "height",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "frame_count",
|
||||
"type": "INT",
|
||||
"links": [
|
||||
17
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 4
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "FrameMakerBatch"
|
||||
},
|
||||
"widgets_values": [
|
||||
4,
|
||||
"false",
|
||||
"top right to bottom left",
|
||||
50,
|
||||
"front",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
"center",
|
||||
"true",
|
||||
768,
|
||||
768,
|
||||
"false",
|
||||
512,
|
||||
512,
|
||||
"false"
|
||||
],
|
||||
"color": "#111111",
|
||||
"bgcolor": "#482b6e",
|
||||
"shape": 1
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"type": "FrameMaker",
|
||||
"pos": [
|
||||
370,
|
||||
60
|
||||
],
|
||||
"size": {
|
||||
"0": 342.5999755859375,
|
||||
"1": 610
|
||||
},
|
||||
"flags": {},
|
||||
"order": 2,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "subject_image",
|
||||
"type": "IMAGE",
|
||||
"link": 1,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "subject_alpha",
|
||||
"type": "MASK",
|
||||
"link": 2
|
||||
},
|
||||
{
|
||||
"name": "bg1",
|
||||
"type": "IMAGE",
|
||||
"link": 4,
|
||||
"slot_index": 2
|
||||
},
|
||||
{
|
||||
"name": "bg2",
|
||||
"type": "IMAGE",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "bg3",
|
||||
"type": "IMAGE",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "bg4",
|
||||
"type": "IMAGE",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "frames",
|
||||
"type": "IMAGE",
|
||||
"link": null
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "frames",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
8
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "subject_image",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
9
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
},
|
||||
{
|
||||
"name": "width",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "height",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "frame_count",
|
||||
"type": "INT",
|
||||
"links": [
|
||||
11
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 4
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "FrameMaker"
|
||||
},
|
||||
"widgets_values": [
|
||||
16,
|
||||
"false",
|
||||
"left to center",
|
||||
50,
|
||||
"front",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
"center",
|
||||
"true",
|
||||
768,
|
||||
768,
|
||||
"false",
|
||||
512,
|
||||
512,
|
||||
"false"
|
||||
],
|
||||
"color": "#111111",
|
||||
"bgcolor": "#482b6e",
|
||||
"shape": 1
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"type": "FrameMakerBatch",
|
||||
"pos": [
|
||||
1110,
|
||||
70
|
||||
],
|
||||
"size": {
|
||||
"0": 350,
|
||||
"1": 590
|
||||
},
|
||||
"flags": {},
|
||||
"order": 4,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "frames",
|
||||
"type": "IMAGE",
|
||||
"link": 15,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "subject_image",
|
||||
"type": "IMAGE",
|
||||
"link": 16
|
||||
},
|
||||
{
|
||||
"name": "subject_alpha",
|
||||
"type": "MASK",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "frame_count",
|
||||
"type": "INT",
|
||||
"link": 17,
|
||||
"widget": {
|
||||
"name": "frame_count"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "frames",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
22
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "subject_image",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
23
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
},
|
||||
{
|
||||
"name": "width",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "height",
|
||||
"type": "INT",
|
||||
"links": [],
|
||||
"shape": 3,
|
||||
"slot_index": 3
|
||||
},
|
||||
{
|
||||
"name": "frame_count",
|
||||
"type": "INT",
|
||||
"links": [
|
||||
25
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 4
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "FrameMakerBatch"
|
||||
},
|
||||
"widgets_values": [
|
||||
4,
|
||||
"false",
|
||||
"center to right",
|
||||
50,
|
||||
"back",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
"center",
|
||||
"true",
|
||||
768,
|
||||
768,
|
||||
"false",
|
||||
512,
|
||||
512,
|
||||
"false"
|
||||
],
|
||||
"color": "#111111",
|
||||
"bgcolor": "#482b6e",
|
||||
"shape": 1
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"type": "FrameMakerBatch",
|
||||
"pos": [
|
||||
1480,
|
||||
70
|
||||
],
|
||||
"size": {
|
||||
"0": 350,
|
||||
"1": 590
|
||||
},
|
||||
"flags": {},
|
||||
"order": 5,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "frames",
|
||||
"type": "IMAGE",
|
||||
"link": 22,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "subject_image",
|
||||
"type": "IMAGE",
|
||||
"link": 23
|
||||
},
|
||||
{
|
||||
"name": "subject_alpha",
|
||||
"type": "MASK",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "frame_count",
|
||||
"type": "INT",
|
||||
"link": 25,
|
||||
"widget": {
|
||||
"name": "frame_count"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "frames",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
21
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "subject_image",
|
||||
"type": "IMAGE",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "width",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "height",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
},
|
||||
{
|
||||
"name": "frame_count",
|
||||
"type": "INT",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "FrameMakerBatch"
|
||||
},
|
||||
"widgets_values": [
|
||||
4,
|
||||
"false",
|
||||
"bottom left to center",
|
||||
50,
|
||||
"front",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
"center",
|
||||
"true",
|
||||
768,
|
||||
768,
|
||||
"false",
|
||||
512,
|
||||
512,
|
||||
"false"
|
||||
],
|
||||
"color": "#111111",
|
||||
"bgcolor": "#482b6e",
|
||||
"shape": 1
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"type": "RIFE VFI",
|
||||
"pos": [
|
||||
1850,
|
||||
70
|
||||
],
|
||||
"size": {
|
||||
"0": 319.9336853027344,
|
||||
"1": 309.7534484863281
|
||||
},
|
||||
"flags": {
|
||||
"collapsed": true
|
||||
},
|
||||
"order": 6,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "frames",
|
||||
"type": "IMAGE",
|
||||
"link": 21
|
||||
},
|
||||
{
|
||||
"name": "optional_interpolation_states",
|
||||
"type": "INTERPOLATION_STATES",
|
||||
"link": null
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
27
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "RIFE VFI"
|
||||
},
|
||||
"widgets_values": [
|
||||
"rife47.pth",
|
||||
10,
|
||||
2,
|
||||
true,
|
||||
true,
|
||||
1
|
||||
],
|
||||
"shape": 1
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"type": "LoadImage",
|
||||
"pos": [
|
||||
20,
|
||||
420
|
||||
],
|
||||
"size": [
|
||||
320,
|
||||
410
|
||||
],
|
||||
"flags": {},
|
||||
"order": 1,
|
||||
"mode": 0,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
4
|
||||
],
|
||||
"shape": 3,
|
||||
"slot_index": 0
|
||||
},
|
||||
{
|
||||
"name": "MASK",
|
||||
"type": "MASK",
|
||||
"links": [],
|
||||
"shape": 3,
|
||||
"slot_index": 1
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "LoadImage"
|
||||
},
|
||||
"widgets_values": [
|
||||
"gm_forest_00008_.png",
|
||||
"image"
|
||||
],
|
||||
"shape": 1
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"type": "VHS_VideoCombine",
|
||||
"pos": [
|
||||
1850,
|
||||
110
|
||||
],
|
||||
"size": [
|
||||
530,
|
||||
810
|
||||
],
|
||||
"flags": {},
|
||||
"order": 7,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 27
|
||||
},
|
||||
{
|
||||
"name": "audio",
|
||||
"type": "VHS_AUDIO",
|
||||
"link": null
|
||||
},
|
||||
{
|
||||
"name": "batch_manager",
|
||||
"type": "VHS_BatchManager",
|
||||
"link": null
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "Filenames",
|
||||
"type": "VHS_FILENAMES",
|
||||
"links": null,
|
||||
"shape": 3
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "VHS_VideoCombine"
|
||||
},
|
||||
"widgets_values": {
|
||||
"frame_rate": 32,
|
||||
"loop_count": 0,
|
||||
"filename_prefix": "AnimateDiff",
|
||||
"format": "video/h264-mp4",
|
||||
"pix_fmt": "yuv420p",
|
||||
"crf": 19,
|
||||
"save_metadata": true,
|
||||
"pingpong": false,
|
||||
"save_output": true,
|
||||
"videopreview": {
|
||||
"hidden": false,
|
||||
"paused": false,
|
||||
"params": {
|
||||
"filename": "AnimateDiff_00002.mp4",
|
||||
"subfolder": "",
|
||||
"type": "output",
|
||||
"format": "video/h264-mp4"
|
||||
}
|
||||
}
|
||||
},
|
||||
"shape": 1
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
[
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
"MASK"
|
||||
],
|
||||
[
|
||||
4,
|
||||
4,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
8,
|
||||
1,
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
9,
|
||||
1,
|
||||
1,
|
||||
10,
|
||||
1,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
11,
|
||||
1,
|
||||
4,
|
||||
10,
|
||||
3,
|
||||
"INT"
|
||||
],
|
||||
[
|
||||
15,
|
||||
10,
|
||||
0,
|
||||
11,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
16,
|
||||
10,
|
||||
1,
|
||||
11,
|
||||
1,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
17,
|
||||
10,
|
||||
4,
|
||||
11,
|
||||
3,
|
||||
"INT"
|
||||
],
|
||||
[
|
||||
21,
|
||||
12,
|
||||
0,
|
||||
6,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
22,
|
||||
11,
|
||||
0,
|
||||
12,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
23,
|
||||
11,
|
||||
1,
|
||||
12,
|
||||
1,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
25,
|
||||
11,
|
||||
4,
|
||||
12,
|
||||
3,
|
||||
"INT"
|
||||
],
|
||||
[
|
||||
27,
|
||||
6,
|
||||
0,
|
||||
15,
|
||||
0,
|
||||
"IMAGE"
|
||||
]
|
||||
],
|
||||
"groups": [],
|
||||
"config": {},
|
||||
"extra": {},
|
||||
"version": 0.4
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 462 KiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 582 KiB |
Reference in New Issue
Block a user