fixed server side logics for trimming, etc.

This commit is contained in:
bruefire
2023-12-10 07:26:23 +09:00
parent 067b486e33
commit cf8302ea10
5 changed files with 69 additions and 27 deletions
+18 -24
View File
@@ -1,4 +1,5 @@
import os
import sys
import torch
import numpy as np
from PIL import Image, ImageOps
@@ -9,11 +10,11 @@ class LoadImagesFromDirInpaint:
def INPUT_TYPES(s):
return {
"required": {
"images_id": ("STRING", {"frames_upload": True}),
"sequence_id": ("STRING", {"frames_upload": True}),
},
"optional": {
"image_load_cap": ("INT", {"default": 0, "min": 0, "step": 1}),
"start_index": ("INT", {"default": 0, "min": 0, "step": 1}),
"end_index": ("INT", {"default": 0, "min": 0, "step": 1}),
}
}
@@ -24,11 +25,16 @@ class LoadImagesFromDirInpaint:
CATEGORY = "image"
def load_images(self, images_id: str, image_load_cap: int = 0, start_index: int = 0):
def load_images(self, sequence_id: str, start_index: int = 0, end_index: int = 0):
if start_index != 0:
start_index -= 1
if end_index == 0:
end_index = sys.maxsize
comfy_custom_dir = os.path.dirname(os.path.abspath(__file__))
comfy_root_dir = os.path.join(comfy_custom_dir, "..", "..")
pathParts = images_id.split(":")
pathParts = sequence_id.split(":")
vframeIds = pathParts[len(pathParts) - 1].split("/")
filenames = pathParts[:-1]
@@ -37,7 +43,7 @@ class LoadImagesFromDirInpaint:
if len(vframeIds) == 1:
imageDir = os.path.join(comfy_root_dir, "input", "extVideoFrame" + vframeIds[0])
images = self.load_from_dir(imageDir, image_load_cap, start_index)
images = self.load_from_dir(imageDir, end_index, start_index)
masks = [image.clone() for image in images]
for mask in masks:
mask.fill_(0)
@@ -46,30 +52,24 @@ class LoadImagesFromDirInpaint:
maskDir = os.path.join(comfy_root_dir, "input", "extVideoFrame" + vframeIds[1])
sketchDir = os.path.join(comfy_root_dir, "input", "extVideoFrame" + vframeIds[2])
images = self.load_from_dir_sketch(imageDir, sketchDir, image_load_cap, start_index)
masks = self.load_from_dir(maskDir, image_load_cap, start_index)
images = self.load_from_dir_sketch(imageDir, sketchDir, end_index, start_index)
masks = self.load_from_dir(maskDir, end_index, start_index)
return (torch.cat(images, dim=0), torch.cat(masks, dim=0), len(images))
def load_from_dir(self, imageDir, image_load_cap, start_index):
def load_from_dir(self, imageDir, end_index, start_index):
img_files = self.getImagePaths(imageDir)
img_files = img_files[start_index:]
img_files = img_files[start_index:end_index]
images = []
limit_images = False
if image_load_cap > 0:
limit_images = True
image_count = 0
for image_path in img_files:
if os.path.isdir(image_path):
continue
if limit_images and image_count >= image_load_cap:
break
i = Image.open(image_path)
i = ImageOps.exif_transpose(i)
image = i.convert("RGB")
@@ -85,25 +85,19 @@ class LoadImagesFromDirInpaint:
return images
def load_from_dir_sketch(self, imageDir, sketchDir, image_load_cap, start_index):
def load_from_dir_sketch(self, imageDir, sketchDir, end_index, start_index):
img_files = self.getImagePaths(imageDir)
img_files = img_files[start_index:]
img_files = img_files[start_index:end_index]
skt_files = self.getImagePaths(sketchDir)
skt_files = skt_files[start_index:]
skt_files = skt_files[start_index:end_index]
images = []
limit_images = False
if image_load_cap > 0:
limit_images = True
image_count = 0
for idx, image_path in enumerate(img_files):
if os.path.isdir(image_path):
continue
if limit_images and image_count >= image_load_cap:
break
i = Image.open(image_path)
i = ImageOps.exif_transpose(i).convert("RGBA")
s = Image.open(skt_files[idx])
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) <year> Adam Veldhousen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+1 -1
View File
@@ -126,7 +126,7 @@ class MaskEditorDialog extends ComfyDialog {
text.style.top = "0";
text.style.right = "0";
text.style.fontFamily = "sans-serif";
text.style.fontSize = "15px";
text.style.fontSize = "20px";
text.style.color = "#fff";
text.innerText = content;
return text;
+2 -2
View File
@@ -110,7 +110,7 @@ app.registerExtension({
// widget setting
// Adds an upload button to the nodes
if (nodeData?.input?.required?.images_id?.[1]?.frames_upload === true) {
if (nodeData?.input?.required?.sequence_id?.[1]?.frames_upload === true) {
nodeData.input.required.upload = ["VFRAMESUPLOAD"];
}
},
@@ -118,7 +118,7 @@ app.registerExtension({
{
return {
VFRAMESUPLOAD(node, inputName, inputData, app) {
const idWidget = node.widgets.find((w) => w.name === "images_id");
const idWidget = node.widgets.find((w) => w.name === "sequence_id");
function showImage(name) {
const img = new Image();
+27
View File
@@ -0,0 +1,27 @@
# ComfyUI Sequential Image Loader
## Overview
これはGUI上でフレーム毎にマスキング(とスケッチ)を行うためのComfyUI用の拡張ノードです。
## Usage
### ノードについて
#### input
* sequence_id: 無視してください (内部処理でのみ使います)。
* upload button: ダイアログから動画のフレームを含むディレクトリ世指定します。
* start_index: 開始フレーム番号を指定します。0で無効。
* end_index: 終了フレーム番号を指定します。0で無効。
#### output
* images: 読み込んだフレームデータです。スケッチした場合、その内容が適用されます。
* mask_images: 各フレームのマスクが画像として出力されます。Mask To Imageノード等でマスクデータに変換が必要です。
* image_count: 処理フレーム数。
### マスクエディターについて
1. フレームを読み込んだ後にノードを右クリックして、"Open In MaskEditor"を選択します。
2. 出現したエディタ上でマスキングと必要に応じてスケッチを行います。
## Example
## Other
input/ディレクトリに作業中の一時フレームデータが溜まっていくので、適当なタイミングで使わなくなったデータを削除してください。