Jacob Segal
8 months ago
64 changed files with 1453 additions and 884 deletions
@ -1,2 +1,8 @@
|
||||
@echo off |
||||
..\python_embeded\python.exe .\update.py ..\ComfyUI\ |
||||
pause |
||||
if exist update_new.py ( |
||||
move /y update_new.py update.py |
||||
echo Running updater again since it got updated. |
||||
..\python_embeded\python.exe .\update.py ..\ComfyUI\ --skip_self_update |
||||
) |
||||
if "%~1"=="" pause |
||||
|
@ -1,3 +0,0 @@
|
||||
..\python_embeded\python.exe .\update.py ..\ComfyUI\ |
||||
..\python_embeded\python.exe -s -m pip install --upgrade torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117 xformers -r ../ComfyUI/requirements.txt pygit2 |
||||
pause |
@ -1,11 +0,0 @@
|
||||
@echo off |
||||
..\python_embeded\python.exe .\update.py ..\ComfyUI\ |
||||
echo |
||||
echo This will try to update pytorch and all python dependencies, if you get an error wait for pytorch/xformers to fix their stuff |
||||
echo You should not be running this anyways unless you really have to |
||||
echo |
||||
echo If you just want to update normally, close this and run update_comfyui.bat instead. |
||||
echo |
||||
pause |
||||
..\python_embeded\python.exe -s -m pip install --upgrade torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 xformers -r ../ComfyUI/requirements.txt pygit2 |
||||
pause |
@ -1,71 +0,0 @@
|
||||
name: "Windows Release cu118 dependencies" |
||||
|
||||
on: |
||||
workflow_dispatch: |
||||
# push: |
||||
# branches: |
||||
# - master |
||||
|
||||
jobs: |
||||
build_dependencies: |
||||
env: |
||||
# you need at least cuda 5.0 for some of the stuff compiled here. |
||||
TORCH_CUDA_ARCH_LIST: "5.0+PTX 6.0 6.1 7.0 7.5 8.0 8.6 8.9" |
||||
FORCE_CUDA: 1 |
||||
MAX_JOBS: 1 # will crash otherwise |
||||
DISTUTILS_USE_SDK: 1 # otherwise distutils will complain on windows about multiple versions of msvc |
||||
XFORMERS_BUILD_TYPE: "Release" |
||||
runs-on: windows-latest |
||||
steps: |
||||
- name: Cache Built Dependencies |
||||
uses: actions/cache@v3 |
||||
id: cache-cu118_python_stuff |
||||
with: |
||||
path: cu118_python_deps.tar |
||||
key: ${{ runner.os }}-build-cu118 |
||||
|
||||
- if: steps.cache-cu118_python_stuff.outputs.cache-hit != 'true' |
||||
uses: actions/checkout@v3 |
||||
|
||||
- if: steps.cache-cu118_python_stuff.outputs.cache-hit != 'true' |
||||
uses: actions/setup-python@v4 |
||||
with: |
||||
python-version: '3.10.9' |
||||
|
||||
- if: steps.cache-cu118_python_stuff.outputs.cache-hit != 'true' |
||||
uses: comfyanonymous/cuda-toolkit@test |
||||
id: cuda-toolkit |
||||
with: |
||||
cuda: '11.8.0' |
||||
# copied from xformers github |
||||
- name: Setup MSVC |
||||
uses: ilammy/msvc-dev-cmd@v1 |
||||
- name: Configure Pagefile |
||||
# windows runners will OOM with many CUDA architectures |
||||
# we cheat here with a page file |
||||
uses: al-cheb/configure-pagefile-action@v1.3 |
||||
with: |
||||
minimum-size: 2GB |
||||
# really unfortunate: https://github.com/ilammy/msvc-dev-cmd#name-conflicts-with-shell-bash |
||||
- name: Remove link.exe |
||||
shell: bash |
||||
run: rm /usr/bin/link |
||||
|
||||
- if: steps.cache-cu118_python_stuff.outputs.cache-hit != 'true' |
||||
shell: bash |
||||
run: | |
||||
python -m pip wheel --no-cache-dir torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 -r requirements.txt pygit2 -w ./temp_wheel_dir |
||||
python -m pip install --no-cache-dir ./temp_wheel_dir/* |
||||
echo installed basic |
||||
git clone --recurse-submodules https://github.com/facebookresearch/xformers.git |
||||
cd xformers |
||||
python -m pip install --no-cache-dir wheel setuptools twine |
||||
echo building xformers |
||||
python setup.py bdist_wheel -d ../temp_wheel_dir/ |
||||
cd .. |
||||
rm -rf xformers |
||||
ls -lah temp_wheel_dir |
||||
mv temp_wheel_dir cu118_python_deps |
||||
tar cf cu118_python_deps.tar cu118_python_deps |
||||
|
||||
|
@ -1,37 +0,0 @@
|
||||
name: "Windows Release cu118 dependencies 2" |
||||
|
||||
on: |
||||
workflow_dispatch: |
||||
inputs: |
||||
xformers: |
||||
description: 'xformers version' |
||||
required: true |
||||
type: string |
||||
default: "xformers" |
||||
|
||||
# push: |
||||
# branches: |
||||
# - master |
||||
|
||||
jobs: |
||||
build_dependencies: |
||||
runs-on: windows-latest |
||||
steps: |
||||
- uses: actions/checkout@v3 |
||||
- uses: actions/setup-python@v4 |
||||
with: |
||||
python-version: '3.10.9' |
||||
|
||||
- shell: bash |
||||
run: | |
||||
python -m pip wheel --no-cache-dir torch torchvision torchaudio ${{ inputs.xformers }} --extra-index-url https://download.pytorch.org/whl/cu118 -r requirements.txt pygit2 -w ./temp_wheel_dir |
||||
python -m pip install --no-cache-dir ./temp_wheel_dir/* |
||||
echo installed basic |
||||
ls -lah temp_wheel_dir |
||||
mv temp_wheel_dir cu118_python_deps |
||||
tar cf cu118_python_deps.tar cu118_python_deps |
||||
|
||||
- uses: actions/cache/save@v3 |
||||
with: |
||||
path: cu118_python_deps.tar |
||||
key: ${{ runner.os }}-build-cu118 |
@ -1,79 +0,0 @@
|
||||
name: "Windows Release cu118 packaging" |
||||
|
||||
on: |
||||
workflow_dispatch: |
||||
# push: |
||||
# branches: |
||||
# - master |
||||
|
||||
jobs: |
||||
package_comfyui: |
||||
permissions: |
||||
contents: "write" |
||||
packages: "write" |
||||
pull-requests: "read" |
||||
runs-on: windows-latest |
||||
steps: |
||||
- uses: actions/cache/restore@v3 |
||||
id: cache |
||||
with: |
||||
path: cu118_python_deps.tar |
||||
key: ${{ runner.os }}-build-cu118 |
||||
- shell: bash |
||||
run: | |
||||
mv cu118_python_deps.tar ../ |
||||
cd .. |
||||
tar xf cu118_python_deps.tar |
||||
pwd |
||||
ls |
||||
|
||||
- uses: actions/checkout@v3 |
||||
with: |
||||
fetch-depth: 0 |
||||
persist-credentials: false |
||||
- shell: bash |
||||
run: | |
||||
cd .. |
||||
cp -r ComfyUI ComfyUI_copy |
||||
curl https://www.python.org/ftp/python/3.10.9/python-3.10.9-embed-amd64.zip -o python_embeded.zip |
||||
unzip python_embeded.zip -d python_embeded |
||||
cd python_embeded |
||||
echo 'import site' >> ./python310._pth |
||||
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py |
||||
./python.exe get-pip.py |
||||
./python.exe -s -m pip install ../cu118_python_deps/* |
||||
sed -i '1i../ComfyUI' ./python310._pth |
||||
cd .. |
||||
|
||||
git clone https://github.com/comfyanonymous/taesd |
||||
cp taesd/*.pth ./ComfyUI_copy/models/vae_approx/ |
||||
|
||||
mkdir ComfyUI_windows_portable |
||||
mv python_embeded ComfyUI_windows_portable |
||||
mv ComfyUI_copy ComfyUI_windows_portable/ComfyUI |
||||
|
||||
cd ComfyUI_windows_portable |
||||
|
||||
mkdir update |
||||
cp -r ComfyUI/.ci/update_windows/* ./update/ |
||||
cp -r ComfyUI/.ci/update_windows_cu118/* ./update/ |
||||
cp -r ComfyUI/.ci/windows_base_files/* ./ |
||||
|
||||
cd .. |
||||
|
||||
"C:\Program Files\7-Zip\7z.exe" a -t7z -m0=lzma -mx=8 -mfb=64 -md=32m -ms=on -mf=BCJ2 ComfyUI_windows_portable.7z ComfyUI_windows_portable |
||||
mv ComfyUI_windows_portable.7z ComfyUI/new_ComfyUI_windows_portable_nvidia_cu118_or_cpu.7z |
||||
|
||||
cd ComfyUI_windows_portable |
||||
python_embeded/python.exe -s ComfyUI/main.py --quick-test-for-ci --cpu |
||||
|
||||
ls |
||||
|
||||
- name: Upload binaries to release |
||||
uses: svenstaro/upload-release-action@v2 |
||||
with: |
||||
repo_token: ${{ secrets.GITHUB_TOKEN }} |
||||
file: new_ComfyUI_windows_portable_nvidia_cu118_or_cpu.7z |
||||
tag: "latest" |
||||
overwrite: true |
||||
|
@ -0,0 +1,93 @@
|
||||
""" |
||||
This file is part of ComfyUI. |
||||
Copyright (C) 2024 Stability AI |
||||
|
||||
This program is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. |
||||
""" |
||||
|
||||
import torch |
||||
import torchvision |
||||
from torch import nn |
||||
from .common import LayerNorm2d_op |
||||
|
||||
|
||||
class CNetResBlock(nn.Module): |
||||
def __init__(self, c, dtype=None, device=None, operations=None): |
||||
super().__init__() |
||||
self.blocks = nn.Sequential( |
||||
LayerNorm2d_op(operations)(c, dtype=dtype, device=device), |
||||
nn.GELU(), |
||||
operations.Conv2d(c, c, kernel_size=3, padding=1), |
||||
LayerNorm2d_op(operations)(c, dtype=dtype, device=device), |
||||
nn.GELU(), |
||||
operations.Conv2d(c, c, kernel_size=3, padding=1), |
||||
) |
||||
|
||||
def forward(self, x): |
||||
return x + self.blocks(x) |
||||
|
||||
|
||||
class ControlNet(nn.Module): |
||||
def __init__(self, c_in=3, c_proj=2048, proj_blocks=None, bottleneck_mode=None, dtype=None, device=None, operations=nn): |
||||
super().__init__() |
||||
if bottleneck_mode is None: |
||||
bottleneck_mode = 'effnet' |
||||
self.proj_blocks = proj_blocks |
||||
if bottleneck_mode == 'effnet': |
||||
embd_channels = 1280 |
||||
self.backbone = torchvision.models.efficientnet_v2_s().features.eval() |
||||
if c_in != 3: |
||||
in_weights = self.backbone[0][0].weight.data |
||||
self.backbone[0][0] = operations.Conv2d(c_in, 24, kernel_size=3, stride=2, bias=False, dtype=dtype, device=device) |
||||
if c_in > 3: |
||||
# nn.init.constant_(self.backbone[0][0].weight, 0) |
||||
self.backbone[0][0].weight.data[:, :3] = in_weights[:, :3].clone() |
||||
else: |
||||
self.backbone[0][0].weight.data = in_weights[:, :c_in].clone() |
||||
elif bottleneck_mode == 'simple': |
||||
embd_channels = c_in |
||||
self.backbone = nn.Sequential( |
||||
operations.Conv2d(embd_channels, embd_channels * 4, kernel_size=3, padding=1, dtype=dtype, device=device), |
||||
nn.LeakyReLU(0.2, inplace=True), |
||||
operations.Conv2d(embd_channels * 4, embd_channels, kernel_size=3, padding=1, dtype=dtype, device=device), |
||||
) |
||||
elif bottleneck_mode == 'large': |
||||
self.backbone = nn.Sequential( |
||||
operations.Conv2d(c_in, 4096 * 4, kernel_size=1, dtype=dtype, device=device), |
||||
nn.LeakyReLU(0.2, inplace=True), |
||||
operations.Conv2d(4096 * 4, 1024, kernel_size=1, dtype=dtype, device=device), |
||||
*[CNetResBlock(1024, dtype=dtype, device=device, operations=operations) for _ in range(8)], |
||||
operations.Conv2d(1024, 1280, kernel_size=1, dtype=dtype, device=device), |
||||
) |
||||
embd_channels = 1280 |
||||
else: |
||||
raise ValueError(f'Unknown bottleneck mode: {bottleneck_mode}') |
||||
self.projections = nn.ModuleList() |
||||
for _ in range(len(proj_blocks)): |
||||
self.projections.append(nn.Sequential( |
||||
operations.Conv2d(embd_channels, embd_channels, kernel_size=1, bias=False, dtype=dtype, device=device), |
||||
nn.LeakyReLU(0.2, inplace=True), |
||||
operations.Conv2d(embd_channels, c_proj, kernel_size=1, bias=False, dtype=dtype, device=device), |
||||
)) |
||||
# nn.init.constant_(self.projections[-1][-1].weight, 0) # zero output projection |
||||
self.xl = False |
||||
self.input_channels = c_in |
||||
self.unshuffle_amount = 8 |
||||
|
||||
def forward(self, x): |
||||
x = self.backbone(x) |
||||
proj_outputs = [None for _ in range(max(self.proj_blocks) + 1)] |
||||
for i, idx in enumerate(self.proj_blocks): |
||||
proj_outputs[idx] = self.projections[i](x) |
||||
return proj_outputs |
@ -0,0 +1,42 @@
|
||||
# code adapted from https://github.com/exx8/differential-diffusion |
||||
|
||||
import torch |
||||
|
||||
class DifferentialDiffusion(): |
||||
@classmethod |
||||
def INPUT_TYPES(s): |
||||
return {"required": {"model": ("MODEL", ), |
||||
}} |
||||
RETURN_TYPES = ("MODEL",) |
||||
FUNCTION = "apply" |
||||
CATEGORY = "_for_testing" |
||||
INIT = False |
||||
|
||||
def apply(self, model): |
||||
model = model.clone() |
||||
model.set_model_denoise_mask_function(self.forward) |
||||
return (model,) |
||||
|
||||
def forward(self, sigma: torch.Tensor, denoise_mask: torch.Tensor, extra_options: dict): |
||||
model = extra_options["model"] |
||||
step_sigmas = extra_options["sigmas"] |
||||
sigma_to = model.inner_model.model_sampling.sigma_min |
||||
if step_sigmas[-1] > sigma_to: |
||||
sigma_to = step_sigmas[-1] |
||||
sigma_from = step_sigmas[0] |
||||
|
||||
ts_from = model.inner_model.model_sampling.timestep(sigma_from) |
||||
ts_to = model.inner_model.model_sampling.timestep(sigma_to) |
||||
current_ts = model.inner_model.model_sampling.timestep(sigma[0]) |
||||
|
||||
threshold = (current_ts - ts_to) / (ts_from - ts_to) |
||||
|
||||
return (denoise_mask >= threshold).to(denoise_mask.dtype) |
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = { |
||||
"DifferentialDiffusion": DifferentialDiffusion, |
||||
} |
||||
NODE_DISPLAY_NAME_MAPPINGS = { |
||||
"DifferentialDiffusion": "Differential Diffusion", |
||||
} |
@ -0,0 +1,49 @@
|
||||
import torch |
||||
import comfy.model_management |
||||
|
||||
from kornia.morphology import dilation, erosion, opening, closing, gradient, top_hat, bottom_hat |
||||
|
||||
|
||||
class Morphology: |
||||
@classmethod |
||||
def INPUT_TYPES(s): |
||||
return {"required": {"image": ("IMAGE",), |
||||
"operation": (["erode", "dilate", "open", "close", "gradient", "bottom_hat", "top_hat"],), |
||||
"kernel_size": ("INT", {"default": 3, "min": 3, "max": 999, "step": 1}), |
||||
}} |
||||
|
||||
RETURN_TYPES = ("IMAGE",) |
||||
FUNCTION = "process" |
||||
|
||||
CATEGORY = "image/postprocessing" |
||||
|
||||
def process(self, image, operation, kernel_size): |
||||
device = comfy.model_management.get_torch_device() |
||||
kernel = torch.ones(kernel_size, kernel_size, device=device) |
||||
image_k = image.to(device).movedim(-1, 1) |
||||
if operation == "erode": |
||||
output = erosion(image_k, kernel) |
||||
elif operation == "dilate": |
||||
output = dilation(image_k, kernel) |
||||
elif operation == "open": |
||||
output = opening(image_k, kernel) |
||||
elif operation == "close": |
||||
output = closing(image_k, kernel) |
||||
elif operation == "gradient": |
||||
output = gradient(image_k, kernel) |
||||
elif operation == "top_hat": |
||||
output = top_hat(image_k, kernel) |
||||
elif operation == "bottom_hat": |
||||
output = bottom_hat(image_k, kernel) |
||||
else: |
||||
raise ValueError(f"Invalid operation {operation} for morphology. Must be one of 'erode', 'dilate', 'open', 'close', 'gradient', 'tophat', 'bottomhat'") |
||||
img_out = output.to(comfy.model_management.intermediate_device()).movedim(1, -1) |
||||
return (img_out,) |
||||
|
||||
NODE_CLASS_MAPPINGS = { |
||||
"Morphology": Morphology, |
||||
} |
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = { |
||||
"Morphology": "ImageMorphology", |
||||
} |
@ -0,0 +1,35 @@
|
||||
import os |
||||
import shutil |
||||
|
||||
base_path = os.path.dirname(os.path.realpath(__file__)) |
||||
|
||||
|
||||
def update_windows_updater(): |
||||
top_path = os.path.dirname(base_path) |
||||
updater_path = os.path.join(base_path, ".ci/update_windows/update.py") |
||||
bat_path = os.path.join(base_path, ".ci/update_windows/update_comfyui.bat") |
||||
|
||||
dest_updater_path = os.path.join(top_path, "update/update.py") |
||||
dest_bat_path = os.path.join(top_path, "update/update_comfyui.bat") |
||||
dest_bat_deps_path = os.path.join(top_path, "update/update_comfyui_and_python_dependencies.bat") |
||||
|
||||
try: |
||||
with open(dest_bat_path, 'rb') as f: |
||||
contents = f.read() |
||||
except: |
||||
return |
||||
|
||||
if not contents.startswith(b"..\\python_embeded\\python.exe .\\update.py"): |
||||
return |
||||
|
||||
shutil.copy(updater_path, dest_updater_path) |
||||
try: |
||||
with open(dest_bat_deps_path, 'rb') as f: |
||||
contents = f.read() |
||||
contents = contents.replace(b'..\\python_embeded\\python.exe .\\update.py ..\\ComfyUI\\', b'call update_comfyui.bat nopause') |
||||
with open(dest_bat_deps_path, 'wb') as f: |
||||
f.write(contents) |
||||
except: |
||||
pass |
||||
shutil.copy(bat_path, dest_bat_path) |
||||
print("Updated the windows standalone package updater.") |
@ -0,0 +1,159 @@
|
||||
#This is an example that uses the websockets api and the SaveImageWebsocket node to get images directly without |
||||
#them being saved to disk |
||||
|
||||
import websocket #NOTE: websocket-client (https://github.com/websocket-client/websocket-client) |
||||
import uuid |
||||
import json |
||||
import urllib.request |
||||
import urllib.parse |
||||
|
||||
server_address = "127.0.0.1:8188" |
||||
client_id = str(uuid.uuid4()) |
||||
|
||||
def queue_prompt(prompt): |
||||
p = {"prompt": prompt, "client_id": client_id} |
||||
data = json.dumps(p).encode('utf-8') |
||||
req = urllib.request.Request("http://{}/prompt".format(server_address), data=data) |
||||
return json.loads(urllib.request.urlopen(req).read()) |
||||
|
||||
def get_image(filename, subfolder, folder_type): |
||||
data = {"filename": filename, "subfolder": subfolder, "type": folder_type} |
||||
url_values = urllib.parse.urlencode(data) |
||||
with urllib.request.urlopen("http://{}/view?{}".format(server_address, url_values)) as response: |
||||
return response.read() |
||||
|
||||
def get_history(prompt_id): |
||||
with urllib.request.urlopen("http://{}/history/{}".format(server_address, prompt_id)) as response: |
||||
return json.loads(response.read()) |
||||
|
||||
def get_images(ws, prompt): |
||||
prompt_id = queue_prompt(prompt)['prompt_id'] |
||||
output_images = {} |
||||
current_node = "" |
||||
while True: |
||||
out = ws.recv() |
||||
if isinstance(out, str): |
||||
message = json.loads(out) |
||||
if message['type'] == 'executing': |
||||
data = message['data'] |
||||
if data['prompt_id'] == prompt_id: |
||||
if data['node'] is None: |
||||
break #Execution is done |
||||
else: |
||||
current_node = data['node'] |
||||
else: |
||||
if current_node == 'save_image_websocket_node': |
||||
images_output = output_images.get(current_node, []) |
||||
images_output.append(out[8:]) |
||||
output_images[current_node] = images_output |
||||
|
||||
return output_images |
||||
|
||||
prompt_text = """ |
||||
{ |
||||
"3": { |
||||
"class_type": "KSampler", |
||||
"inputs": { |
||||
"cfg": 8, |
||||
"denoise": 1, |
||||
"latent_image": [ |
||||
"5", |
||||
0 |
||||
], |
||||
"model": [ |
||||
"4", |
||||
0 |
||||
], |
||||
"negative": [ |
||||
"7", |
||||
0 |
||||
], |
||||
"positive": [ |
||||
"6", |
||||
0 |
||||
], |
||||
"sampler_name": "euler", |
||||
"scheduler": "normal", |
||||
"seed": 8566257, |
||||
"steps": 20 |
||||
} |
||||
}, |
||||
"4": { |
||||
"class_type": "CheckpointLoaderSimple", |
||||
"inputs": { |
||||
"ckpt_name": "v1-5-pruned-emaonly.ckpt" |
||||
} |
||||
}, |
||||
"5": { |
||||
"class_type": "EmptyLatentImage", |
||||
"inputs": { |
||||
"batch_size": 1, |
||||
"height": 512, |
||||
"width": 512 |
||||
} |
||||
}, |
||||
"6": { |
||||
"class_type": "CLIPTextEncode", |
||||
"inputs": { |
||||
"clip": [ |
||||
"4", |
||||
1 |
||||
], |
||||
"text": "masterpiece best quality girl" |
||||
} |
||||
}, |
||||
"7": { |
||||
"class_type": "CLIPTextEncode", |
||||
"inputs": { |
||||
"clip": [ |
||||
"4", |
||||
1 |
||||
], |
||||
"text": "bad hands" |
||||
} |
||||
}, |
||||
"8": { |
||||
"class_type": "VAEDecode", |
||||
"inputs": { |
||||
"samples": [ |
||||
"3", |
||||
0 |
||||
], |
||||
"vae": [ |
||||
"4", |
||||
2 |
||||
] |
||||
} |
||||
}, |
||||
"save_image_websocket_node": { |
||||
"class_type": "SaveImageWebsocket", |
||||
"inputs": { |
||||
"images": [ |
||||
"8", |
||||
0 |
||||
] |
||||
} |
||||
} |
||||
} |
||||
""" |
||||
|
||||
prompt = json.loads(prompt_text) |
||||
#set the text prompt for our positive CLIPTextEncode |
||||
prompt["6"]["inputs"]["text"] = "masterpiece best quality man" |
||||
|
||||
#set the seed for our KSampler node |
||||
prompt["3"]["inputs"]["seed"] = 5 |
||||
|
||||
ws = websocket.WebSocket() |
||||
ws.connect("ws://{}/ws?clientId={}".format(server_address, client_id)) |
||||
images = get_images(ws, prompt) |
||||
|
||||
#Commented out code to display the output images: |
||||
|
||||
# for node_id in images: |
||||
# for image_data in images[node_id]: |
||||
# from PIL import Image |
||||
# import io |
||||
# image = Image.open(io.BytesIO(image_data)) |
||||
# image.show() |
||||
|
Loading…
Reference in new issue