45th's picture
Upload 3 files
ee0d610 verified
Raw History Blame Contribute Delete
3.38 kB
import os
import time
import torch
import folder_paths
from server import PromptServer
from aiohttp import web
from PIL import Image
import numpy as np
CACHE_DIR = os.path.join(folder_paths.get_temp_directory(), "image_chooser_cache")
os.makedirs(CACHE_DIR, exist_ok=True)
# Глобальный словарь для связи бэкенда и фронтенда
CHOICES = {}
class ImageChooser:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image_A": ("IMAGE",),
"image_B": ("IMAGE",),
},
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "my_id": "UNIQUE_ID"},
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "execute"
CATEGORY = "utils"
# ЭТОТ МЕТОД РЕШАЕТ ПРОБЛЕМУ КЭША:
# Возвращает текущее время. ComfyUI видит, что значение изменилось,
# аннулирует кэш этой ноды и заставляет её запускаться при каждом Queue Prompt.
@classmethod
def IS_CHANGED(cls, **kwargs):
return time.time()
def execute(self, image_A, image_B, prompt=None, extra_pnginfo=None, my_id=None):
my_id_str = str(my_id)
# Перезаписываем картинки свежими кадрами
self.save_temp_image(image_A, f"{my_id_str}_A.png")
self.save_temp_image(image_B, f"{my_id_str}_B.png")
# Обязательно сбрасываем старый выбор пользователя для этой конкретной ноды
CHOICES[my_id_str] = None
# Отправляем сигнал браузеру открыть модальное окно
PromptServer.instance.send_sync("image_chooser_wait", {"node_id": my_id_str})
print(f"[Image Chooser] Workflow paused. Waiting for user selection on node {my_id_str}...")
# Ждем клика
while CHOICES.get(my_id_str) is None:
time.sleep(0.1)
choice = CHOICES.pop(my_id_str)
print(f"[Image Chooser] Pause lifted. Result received: {choice}")
if choice == "CANCEL":
raise Exception("Execution cancelled by user via Image Chooser.")
if choice == "A":
return (image_A,)
else:
return (image_B,)
def save_temp_image(self, tensor, filename):
if len(tensor.shape) == 4:
img_np = tensor[0].cpu().numpy()
else:
img_np = tensor.cpu().numpy()
img_np = np.clip(img_np * 255.0, 0, 255).astype(np.uint8)
img = Image.fromarray(img_np)
img.save(os.path.join(CACHE_DIR, filename))
@PromptServer.instance.routes.post("/image_chooser/select")
async def handle_select(request):
json_data = await request.json()
node_id = str(json_data.get("node_id"))
choice = json_data.get("choice")
CHOICES[node_id] = choice
return web.json_response({"status": "success"})
NODE_CLASS_MAPPINGS = {
"ImageChooser": ImageChooser
}
NODE_DISPLAY_NAME_MAPPINGS = {
"ImageChooser": "Image Chooser"
}
WEB_DIRECTORY = "."