Add files via upload

This commit is contained in:
mercu-lore
2025-11-12 15:37:58 +01:00
committed by GitHub
parent 29122335fe
commit d5f34d6fec
4 changed files with 78 additions and 52 deletions
+15 -4
View File
@@ -87,11 +87,22 @@ class BoxReinsertNode:
y1 = box_meta.get("y1", 0)
y2 = box_meta.get("y2", 0)
# Applica fattore di scala se la preview era stata scalata
display_scale_factor = box_meta.get("displayScaleFactor", 1.0)
if display_scale_factor and display_scale_factor != 1.0:
# Se le coordinate sono state prese da una preview scalata,
# dividi per il fattore di scala per ottenere le coordinate originali
x1 = x1 / display_scale_factor
x2 = x2 / display_scale_factor
y1 = y1 / display_scale_factor
y2 = y2 / display_scale_factor
print(f"[BoxReinsertNode] Scale factor detected: {display_scale_factor}x. Adjusted coordinates.")
# Normalizza coordinate (assicura che x1 < x2, y1 < y2)
box_x_start = min(x1, x2)
box_x_end = max(x1, x2)
box_y_start = min(y1, y2)
box_y_end = max(y1, y2)
box_x_start = int(round(min(x1, x2)))
box_x_end = int(round(max(x1, x2)))
box_y_start = int(round(min(y1, y2)))
box_y_end = int(round(max(y1, y2)))
crop_width = box_x_end - box_x_start
crop_height = box_y_end - box_y_start
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "ComfyUI-BoxBox"
description = "BoxBox is a lightweight ComfyUI extension for visualizing image boxes and controlling regions interactively inside the node interface."
version = "1.0.0"
version = "1.0.1"
license = {file = "LICENSE"}
# classifiers = [
# # For OS-independent nodes (works on all operating systems)
+11
View File
@@ -73,6 +73,17 @@ class RegionCropNode:
else:
raise ValueError("No region coordinates provided in metadata")
# Estrai il fattore di scala se la preview era stata scalata
display_scale_factor = metadata.get("displayScaleFactor", 1.0)
if display_scale_factor and display_scale_factor != 1.0:
# Se le coordinate sono state prese da una preview scalata,
# dividi per il fattore di scala per ottenere le coordinate originali
x1 = x1 / display_scale_factor
x2 = x2 / display_scale_factor
y1 = y1 / display_scale_factor
y2 = y2 / display_scale_factor
print(f"[BoxCrop] Scale factor detected: {display_scale_factor}x. Adjusted coordinates.")
# Assicura che le coordinate siano integer
x1 = int(round(x1))
x2 = int(round(x2))
+51 -47
View File
@@ -1,45 +1,29 @@
"""
Region Selector Node - Nodo per selezionare regioni di immagini con interfaccia popup
Region Selector Node - con endpoint di ridimensionamento lato backend.
Riduce automaticamente le immagini oltre 1024px quando viene aperta
l'interfaccia "Select Box", salvandole in /temp/.
"""
import os
import json
from PIL import Image
import folder_paths
import server
class RegionSelectorNode:
"""
Nodo che permette di selezionare una regione rettangolare su un'immagine
tramite un'interfaccia interattiva in popup.
Outputs:
- IMAGE: L'immagine passata
- STRING: Metadata JSON con coordinate della regione selezionata
"""
def __init__(self):
# Metadata di default con coordinate x1, x2, y1, y2 (lati, non posizione+dimensioni)
self.last_metadata = json.dumps({
"x1": 0,
"y1": 0,
"x2": 0,
"y2": 0,
"zoom": 1,
"borderWidth": 0,
"borderPosition": "inside",
"selected": False
"x1": 0, "y1": 0, "x2": 0, "y2": 0,
"zoom": 1, "borderWidth": 0,
"borderPosition": "inside", "selected": False
})
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
},
"optional": {
"region_metadata": ("STRING", {
"default": "{}",
"multiline": True,
}),
}
"required": {"image": ("IMAGE",)},
"optional": {"region_metadata": ("STRING", {"default": "{}", "multiline": True})}
}
RETURN_TYPES = ("IMAGE", "STRING")
@@ -49,27 +33,47 @@ class RegionSelectorNode:
OUTPUT_NODE = True
def process_region_selection(self, image, region_metadata="{}"):
"""
Processa l'immagine e ritorna l'immagine + metadata della regione selezionata.
Args:
image: Tensor immagine (B, H, W, C)
region_metadata: JSON string con coordinate della regione (x1, x2, y1, y2)
Returns:
(image, region_metadata_json): Immagine originale e metadata JSON
"""
# Usa il metadata fornito, o l'ultimo salvato se vuoto
if region_metadata and region_metadata.strip() and region_metadata != "{}":
metadata_to_return = region_metadata
if region_metadata.strip() and region_metadata != "{}":
self.last_metadata = region_metadata
else:
# Se nessun metadata è stato fornito, usa l'ultimo salvato
metadata_to_return = self.last_metadata
return (image, self.last_metadata)
print(f"[RegionSelectorNode] Processing selection, metadata: {metadata_to_return}")
return (image, metadata_to_return)
def scale_image_if_needed(filename, max_size=1024):
input_path = folder_paths.get_input_directory()
full_path = os.path.join(input_path, filename)
if not os.path.exists(full_path):
return {"error": "file non trovato"}
with Image.open(full_path) as im:
w, h = im.size
if w <= max_size and h <= max_size:
return {"scaled": False, "path": f"view?filename={filename}&type=input"}
scale_factor = min(max_size / w, max_size / h)
new_size = (int(w * scale_factor), int(h * scale_factor))
im_resized = im.resize(new_size, Image.Resampling.LANCZOS)
os.makedirs("temp", exist_ok=True)
scaled_name = f"scaled_{filename}"
scaled_path = os.path.join("temp", scaled_name)
im_resized.save(scaled_path)
print(f"[RegionSelector] Immagine scalata {w}x{h} -> {new_size[0]}x{new_size[1]}")
return {"scaled": True, "path": f"view?filename={scaled_name}&type=temp", "scale": scale_factor}
@server.PromptServer.instance.routes.post("/region_selector/scale")
async def scale_image_endpoint(request):
try:
data = await request.json()
filename = data.get("filename")
if not filename:
return {"error": "filename mancante"}
result = scale_image_if_needed(filename)
return result
except Exception as e:
print(f"[RegionSelector] Errore endpoint scale: {e}")
return {"error": str(e)}
NODE_CLASS_MAPPINGS = {"BoxSelector": RegionSelectorNode}