This commit is contained in:
Fill
2025-12-03 02:26:04 -08:00
parent ca4a195229
commit 7128f930c3
4 changed files with 28 additions and 28 deletions
+3 -3
View File
@@ -105,7 +105,7 @@ from .nodes.image.FL_ImageBatchToGrid import FL_ImageBatchToGrid
from .nodes.image.FL_ImageNotes import FL_ImageNotes
from .nodes.image.FL_ImageOverlay import FL_ImageOverlay
from .nodes.image.FL_ImageSelector import FL_ImageSelector
from .nodes.image.FL_ImageSelectPicker import FL_ImageSelectPicker
from .nodes.image.FL_ImagePicker import FL_ImagePicker
from .nodes.image.FL_ImageSlicer import FL_ImageSlicer
from .nodes.image.FL_Image_AddToBatch import FL_ImageAddToBatch
from .nodes.image.FL_Image_Blank import FL_ImageBlank
@@ -317,7 +317,7 @@ NODE_CLASS_MAPPINGS = {
"FL_Math": FL_Math,
"FL_ImageSlicer": FL_ImageSlicer,
"FL_ImageSelector": FL_ImageSelector,
"FL_ImageSelectPicker": FL_ImageSelectPicker,
"FL_ImagePicker": FL_ImagePicker,
"FL_ImageOverlay": FL_ImageOverlay,
"FL_ImageAspectCropper": FL_ImageAspectCropper,
"FL_HF_UploaderAbsolute": FL_HF_UploaderAbsolute,
@@ -506,7 +506,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"FL_Math": "FL Math",
"FL_ImageSlicer": "FL Image Slicer",
"FL_ImageSelector": "FL Image Selector",
"FL_ImageSelectPicker": "FL Image Select Picker",
"FL_ImagePicker": "FL Image Picker",
"FL_ImageOverlay": "FL Image Overlay",
"FL_ImageAspectCropper": "FL Image Aspect Cropper",
"FL_HF_UploaderAbsolute": "FL HF Uploader Absolute",
@@ -1,4 +1,4 @@
# FL_ImageSelectPicker: Interactive image selector with modal UI
# FL_ImagePicker: Interactive image selector with modal UI
import os
import io
import base64
@@ -21,7 +21,7 @@ class InterruptProcessing(Exception):
pass
class FL_ImageSelectPicker:
class FL_ImagePicker:
"""
An interactive image selector node that pauses execution and displays
a modal UI for the user to select which images to keep from a batch.
@@ -77,7 +77,7 @@ class FL_ImageSelectPicker:
# Convert images to thumbnails for sending to frontend (faster loading)
# Original full-res images are kept in pending_selections for output
image_data = []
print(f"[FL_ImageSelectPicker] Generating thumbnails for {batch_size} images...")
print(f"[FL_ImagePicker] Generating thumbnails for {batch_size} images...")
for i in range(batch_size):
img_tensor = images[i]
# Convert tensor to PIL
@@ -112,14 +112,14 @@ class FL_ImageSelectPicker:
}
# Send message to frontend to show selector
PromptServer.instance.send_sync("fl_image_selector_show", {
PromptServer.instance.send_sync("fl_image_picker_show", {
"session_id": session_id,
"images": image_data,
"batch_size": batch_size,
"timeout_seconds": timeout_seconds
})
print(f"[FL_ImageSelectPicker] Waiting for user selection... (timeout: {timeout_seconds}s)")
print(f"[FL_ImagePicker] Waiting for user selection... (timeout: {timeout_seconds}s)")
# Block until user responds or timeout
event_set = event.wait(timeout=timeout_seconds)
@@ -135,7 +135,7 @@ class FL_ImageSelectPicker:
if not event_set:
# Timeout - cancel the execution
print(f"[FL_ImageSelectPicker] Timeout reached. Cancelling execution...")
print(f"[FL_ImagePicker] Timeout reached. Cancelling execution...")
nodes = execution.nodes
if hasattr(nodes, 'interrupt_processing'):
nodes.interrupt_processing()
@@ -143,7 +143,7 @@ class FL_ImageSelectPicker:
if cancelled:
# User cancelled - interrupt the execution
print(f"[FL_ImageSelectPicker] Selection cancelled by user. Interrupting execution...")
print(f"[FL_ImagePicker] Selection cancelled by user. Interrupting execution...")
# Set the interrupt flag in ComfyUI's execution module
nodes = execution.nodes
if hasattr(nodes, 'interrupt_processing'):
@@ -153,7 +153,7 @@ class FL_ImageSelectPicker:
if selection is None or len(selection) == 0:
# No selection - return all
print(f"[FL_ImageSelectPicker] No images selected. Returning all {batch_size} images.")
print(f"[FL_ImagePicker] No images selected. Returning all {batch_size} images.")
return (images, f"No selection: returned all {batch_size} images")
# Filter to selected indices
@@ -161,13 +161,13 @@ class FL_ImageSelectPicker:
selected_images = images[selected_indices]
info = f"Selected {len(selected_indices)} of {batch_size} images: indices {selected_indices}"
print(f"[FL_ImageSelectPicker] {info}")
print(f"[FL_ImagePicker] {info}")
return (selected_images, info)
# API endpoint to receive selection from frontend
@PromptServer.instance.routes.post("/fl_image_select_picker/select")
@PromptServer.instance.routes.post("/fl_image_picker/select")
async def receive_selection(request):
try:
data = await request.json()
@@ -187,7 +187,7 @@ async def receive_selection(request):
# API endpoint to check if a session is still active (for frontend to detect if node was interrupted)
@PromptServer.instance.routes.get("/fl_image_select_picker/status/{session_id}")
@PromptServer.instance.routes.get("/fl_image_picker/status/{session_id}")
async def check_status(request):
session_id = request.match_info.get("session_id")
if session_id in pending_selections:
@@ -197,7 +197,7 @@ async def check_status(request):
# API endpoint to fetch full-res image on demand for preview
@PromptServer.instance.routes.get("/fl_image_select_picker/full_image/{session_id}/{index}")
@PromptServer.instance.routes.get("/fl_image_picker/full_image/{session_id}/{index}")
async def get_full_image(request):
try:
session_id = request.match_info.get("session_id")
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui_fill-nodes"
description = "Fill-Nodes is a versatile collection of custom nodes for ComfyUI that extends functionality across multiple domains. Features include advanced image processing (pixelation, slicing, masking), visual effects generation (glitch, halftone, pixel art), comprehensive file handling (PDF creation/extraction, Google Drive integration), AI model interfaces (GPT, DALL-E, Hugging Face), utility nodes for workflow enhancement, and specialized tools for video processing, captioning, and batch operations. The pack provides both practical workflow solutions and creative tools within a unified node collection."
version = "2.2.0"
version = "2.2.1"
license = "LICENSE"
dependencies = ["diffusers", "librosa", "sounddevice", "glitch_this", "PyOpenGL", "glfw", "scipy>=1.13.1", "requests", "aiohttp", "moviepy", "matplotlib", "reportlab", "openai", "PyPDF2", "pdf2image", "PyMuPDF", "reportlab", "PyPDF2", "ollama", "kornia", "opencv-python", "gdown", "open_clip_torch", "google-genai"]
@@ -1,5 +1,5 @@
/**
* FL_ImageSelectPicker.js
* FL_ImagePicker.js
* Interactive modal for selecting images from a batch
*/
@@ -15,10 +15,10 @@ let currentSessionId = null;
let currentBatchSize = 0;
// Listen for the show selector event from the backend
api.addEventListener("fl_image_selector_show", (event) => {
api.addEventListener("fl_image_picker_show", (event) => {
const { session_id, images, batch_size, timeout_seconds } = event.detail;
console.log(`[FL_ImageSelectPicker] Received ${batch_size} images for selection (timeout: ${timeout_seconds}s)`);
showImageSelectorModal(session_id, images, batch_size, timeout_seconds || 300);
console.log(`[FL_ImagePicker] Received ${batch_size} images for selection (timeout: ${timeout_seconds}s)`);
showImagePickerModal(session_id, images, batch_size, timeout_seconds || 300);
});
function formatTime(seconds) {
@@ -27,7 +27,7 @@ function formatTime(seconds) {
return `${mins}:${secs.toString().padStart(2, '0')}`;
}
function showImageSelectorModal(sessionId, images, batchSize, timeoutSeconds) {
function showImagePickerModal(sessionId, images, batchSize, timeoutSeconds) {
// Close any existing modal
if (activeModal) {
activeModal.remove();
@@ -530,7 +530,7 @@ function createButton(text, color, onClick, isPrimary = false) {
async function sendSelection(sessionId, selection, cancelled) {
try {
const response = await fetch('/fl_image_select_picker/select', {
const response = await fetch('/fl_image_picker/select', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -542,9 +542,9 @@ async function sendSelection(sessionId, selection, cancelled) {
})
});
const result = await response.json();
console.log('[FL_ImageSelectPicker] Selection sent:', result);
console.log('[FL_ImagePicker] Selection sent:', result);
} catch (error) {
console.error('[FL_ImageSelectPicker] Error sending selection:', error);
console.error('[FL_ImagePicker] Error sending selection:', error);
}
}
@@ -797,7 +797,7 @@ async function loadFullResImage(index) {
img.style.opacity = '0';
try {
const response = await fetch(`/fl_image_select_picker/full_image/${currentSessionId}/${index}`);
const response = await fetch(`/fl_image_picker/full_image/${currentSessionId}/${index}`);
const data = await response.json();
if (data.status === 'ok') {
@@ -814,7 +814,7 @@ async function loadFullResImage(index) {
spinner.innerHTML = `<span style="color: #d9534f;">Error loading image</span>`;
}
} catch (error) {
console.error('[FL_ImageSelectPicker] Error loading full-res image:', error);
console.error('[FL_ImagePicker] Error loading full-res image:', error);
spinner.innerHTML = `<span style="color: #d9534f;">Error loading image</span>`;
}
}
@@ -916,9 +916,9 @@ function addStyles() {
// Register extension (for node-specific enhancements if needed)
app.registerExtension({
name: "FillNodes.ImageSelectPicker",
name: "FillNodes.ImagePicker",
async nodeCreated(node) {
if (node.comfyClass === "FL_ImageSelectPicker") {
if (node.comfyClass === "FL_ImagePicker") {
// Add any node-specific UI enhancements here
// For example, we could add a status indicator widget
}