Add files via upload

This commit is contained in:
TSC
2023-08-06 22:09:13 -05:00
committed by GitHub
parent 938f2af75f
commit bf93794914
20 changed files with 868 additions and 268 deletions

File diff suppressed because it is too large Load Diff

94
js/efficiency_nodes.js Normal file
View File

@@ -0,0 +1,94 @@
import { app } from "../../scripts/app.js";
const ext = {
name: "BlobURLLogger",
ws: null,
maxCount: 0,
currentCount: 0,
sendBlob: false,
startProcessing: false,
lastBlobURL: null,
debug: false, // Set to true to see debug messages, false to suppress them.
log(...args) {
if (this.debug) {
console.log(...args);
}
},
error(...args) {
if (this.debug) {
console.error(...args);
}
},
async sendBlobDataAsDataURL(blobURL) {
const blob = await fetch(blobURL).then(res => res.blob());
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
const base64data = reader.result;
this.ws.send(base64data);
};
},
handleCommandMessage(data) {
this.maxCount = data.maxCount;
this.sendBlob = data.sendBlob;
this.startProcessing = data.startProcessing;
this.currentCount = 0;
// Check if we should revoke the last Blob URL after processing.
if(!this.startProcessing && this.lastBlobURL) {
this.log("[BlobURLLogger] Revoking last Blob URL:", this.lastBlobURL);
URL.revokeObjectURL(this.lastBlobURL);
this.lastBlobURL = null;
}
},
init() {
this.log("[BlobURLLogger] Initializing...");
this.ws = new WebSocket('ws://127.0.0.1:8288');
this.ws.addEventListener('open', () => {
this.log('[BlobURLLogger] WebSocket connection opened.');
});
this.ws.addEventListener('error', (err) => {
this.error('[BlobURLLogger] WebSocket Error:', err);
});
this.ws.addEventListener('message', (event) => {
try {
const data = JSON.parse(event.data);
if(data.maxCount !== undefined && data.sendBlob !== undefined && data.startProcessing !== undefined) {
this.handleCommandMessage(data);
}
} catch(err) {
this.error('[BlobURLLogger] Error parsing JSON:', err);
}
});
const originalCreateObjectURL = URL.createObjectURL;
URL.createObjectURL = (object) => {
const blobURL = originalCreateObjectURL.call(this, object);
if (blobURL.startsWith('blob:') && this.startProcessing) {
this.log("[BlobURLLogger] Blob URL created:", blobURL);
this.lastBlobURL = blobURL;
if(this.sendBlob && this.currentCount < this.maxCount) {
this.sendBlobDataAsDataURL(blobURL);
}
this.currentCount++;
}
return blobURL;
};
this.log("[BlobURLLogger] Hook attached.");
}
};
app.registerExtension(ext);

View File

@@ -1 +1,2 @@
simpleeval
websockets

View File

@@ -1,10 +1,8 @@
# Efficiency Nodes Utility functions
from torch import Tensor
import torch
from PIL import Image
import numpy as np
import os
import sys
import io
@@ -26,8 +24,10 @@ sys.path.append(comfy_dir)
# Import functions from ComfyUI
import comfy.sd
from comfy.cli_args import args
import latent_preview
# Load my version of Comfy functions
# Load my custom ComfyUI functions
from tsc_sd import *
# Cache for Efficiency Node models
@@ -39,10 +39,12 @@ loaded_objects = {
# Cache for Ksampler (Efficient) Outputs
last_helds: dict[str, list] = {
"results": [], # (results, id) # Preview Images, stored as a pil image list
"preview_images": [], # (preview_images, id) # Preview Images, stored as a pil image list
"latent": [], # (latent, id) # Latent outputs, stored as a latent tensor list
"images": [], # (images, id) # Image outputs, stored as an image tensor list
"vae_decode": [], # (vae_decode, id) # Used to track wether to vae-decode or not
"output_images": [], # (output_images, id) # Output Images, stored as an image tensor list
"vae_decode_flag": [], # (vae_decode, id) # Boolean to track wether vae-decode during Holds
"xy_plot_flag": [], # (xy_plot_flag, id) # Boolean to track if held images are xy_plot results
"xy_plot_image": [], # (xy_plot_image, id) # XY Plot image stored as an image tensor
}
# Tensor to PIL (grabbed from WAS Suite)
@@ -120,7 +122,6 @@ def print_loaded_objects_entries(id=None, prompt=None, show_id=False):
if not entries_found:
print("-")
# This function cleans global variables associated with nodes that are no longer detected on UI
def globals_cleanup(prompt):
global loaded_objects
@@ -388,7 +389,6 @@ def clear_cache_by_exception(node_id, vae_dict=None, ckpt_dict=None, lora_dict=N
if not tuple_item[-1]:
loaded_objects[dict_name].remove(tuple_item)
# Retrieve the cache number from 'node_settings' json file
def get_cache_numbers(node_name):
# Get the directory path of the current file
@@ -412,7 +412,7 @@ def print_last_helds(id=None):
print(f"Node-specific Last Helds (node_id:{int(id)})")
else:
print(f"Global Last Helds:")
for key in ["results", "latent", "images", "vae_decode"]:
for key in ["preview_images", "latent", "output_images", "vae_decode"]:
entries_with_id = last_helds[key] if id is None else [entry for entry in last_helds[key] if id == entry[-1]]
if not entries_with_id: # If no entries with the chosen ID, print None and skip this key
continue
@@ -443,3 +443,106 @@ def suppress_output():
finally:
sys.stdout = original_stdout
sys.stderr = original_stderr
# Set global preview_method
def set_preview_method(method):
if method == 'auto' or method == 'LatentPreviewMethod.Auto':
args.preview_method = latent_preview.LatentPreviewMethod.Auto
elif method == 'latent2rgb' or method == 'LatentPreviewMethod.Latent2RGB':
args.preview_method = latent_preview.LatentPreviewMethod.Latent2RGB
elif method == 'taesd' or method == 'LatentPreviewMethod.TAESD':
args.preview_method = latent_preview.LatentPreviewMethod.TAESD
else:
args.preview_method = latent_preview.LatentPreviewMethod.NoPreviews
# Extract global preview_method
def global_preview_method():
return args.preview_method
#-----------------------------------------------------------------------------------------------------------------------
# Auto install Efficiency Nodes Python packages
import subprocess
def install_packages(required_packages):
installed_packages = packages(versions=False)
for pkg in required_packages:
if pkg not in installed_packages:
print(f"\033[32mEfficiency Nodes:\033[0m Installing {pkg}...")
subprocess.check_call([sys.executable, '-m', 'pip', 'install', pkg])
print(f"\033[32mEfficiency Nodes:\033[0m Installed {pkg}!")
def packages(versions=False):
return [(r.decode().split('==')[0] if not versions else r.decode()) for r in
subprocess.check_output([sys.executable, '-m', 'pip', 'freeze']).split()]
# Packages to install
required_packages = ['simpleeval', 'websockets']
install_packages(required_packages)
#-----------------------------------------------------------------------------------------------------------------------
# Auto install efficiency nodes web extension '\js\efficiency_nodes.js' to 'ComfyUI\web\extensions'
import shutil
# Source and destination paths
source_path = os.path.join(my_dir, 'js', 'efficiency_nodes.js')
destination_dir = os.path.join(comfy_dir, 'web', 'extensions', 'efficiency-nodes-comfyui')
destination_path = os.path.join(destination_dir, 'efficiency_nodes.js')
# Create the destination directory if it doesn't exist
os.makedirs(destination_dir, exist_ok=True)
# Copy the file
shutil.copy2(source_path, destination_path)
#-----------------------------------------------------------------------------------------------------------------------
# Establish a websocket connection to communicate with "efficiency-nodes.js" under:
# ComfyUI\web\extensions\efficiency-nodes-comfyui\
import websockets #https://github.com/python-websockets/websockets
import asyncio
import threading
import base64
from io import BytesIO
from torchvision import transforms
# Import my functions
from tsc_utils import *
latest_image = None
connected_client = None
async def server_logic(websocket, path):
global latest_image, connected_client
# Assign the connected client
connected_client = websocket
async for message in websocket:
# If not a command, treat it as image data
if not message.startswith('{'):
image_data = base64.b64decode(message.split(",")[1])
image = Image.open(BytesIO(image_data))
latest_image = pil2tensor(image)
def run_server():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
start_server = websockets.serve(server_logic, "127.0.0.1", 8288)
loop.run_until_complete(start_server)
loop.run_forever()
def get_latest_image():
return latest_image
# Function to send commands to frontend
def send_command_to_frontend(startListening=False, maxCount=0, sendBlob=False):
global connected_client
if connected_client:
asyncio.run(connected_client.send(json.dumps({
'startProcessing': startListening,
'maxCount': maxCount,
'sendBlob': sendBlob
})))
# Start the WebSocket server in a separate thread
server_thread = threading.Thread(target=run_server)
server_thread.start()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 701 KiB

After

Width:  |  Height:  |  Size: 701 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 764 KiB

After

Width:  |  Height:  |  Size: 638 KiB

BIN
workflows/Thumbs.db Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -41,3 +41,6 @@ Notes:
For example, if the scheduler isn't specified when plotting Samplers, the script will use
the scheduler set by the Ksampler (Efficient).
- LoRA stacking through the XY Plot Manual Entry node is currently not supported.
- The following XY Plot types are not allowed types in an XY Plot for each of the following KSampler nodes...
1) KSampler (Efficient): "AddNoise", "ReturnNoise", "StartStep", "EndStep"
2) KSampler Adv. (Efficient): "Denoise"

BIN
workflows/XYplot/Thumbs.db Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 MiB

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 MiB

After

Width:  |  Height:  |  Size: 5.7 MiB