Update nodes with new version

This commit is contained in:
unknown
2026-02-18 13:55:04 +07:00
parent af799dee21
commit 23e908f987
3 changed files with 187 additions and 0 deletions
+3
View File
@@ -10,6 +10,7 @@ from .blackextract import *
from .autocrop import *
from .numfunction import *
from .linecounter import *
from .numstrcleanup import *
NODE_CLASS_MAPPINGS = {
"RasterToUniformSVG": RasterToSVGConverter,
@@ -27,6 +28,7 @@ NODE_CLASS_MAPPINGS = {
"RoundUpNode": RoundUpNode,
"RoundDownNode": RoundDownNode,
"CSVValueExtractor": CSVValueExtractor,
"NumberStringCleanup": NumberStringCleanup,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -45,4 +47,5 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"RoundUpNode": "Round Up",
"RoundDownNode": "Round Down",
"CSVValueExtractor": "CSV Value Extractor",
"NumberStringCleanup": "Number String Cleanup",
}
+63
View File
@@ -0,0 +1,63 @@
"""
SVG Path Length Calculator Node for ComfyUI
Calculates the total length of all paths in an SVG file,
ignoring line thickness (stroke-width).
"""
import re
class NumberStringCleanup:
"""
Cleans up a raw string containing a number and converts it
into a two-decimal-place float-compatible string.
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"raw_string": ("STRING", {"default": "", "multiline": False}),
},
}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("cleaned_number",)
FUNCTION = "clean_number"
CATEGORY = "utils/string"
def clean_number(self, raw_string: str):
s = raw_string.strip()
# Remove everything except digits, commas, dots, and minus sign
s = re.sub(r"[^\d.,-]", "", s)
# Replace comma with dot (e.g. "52,25" -> "52.25")
s = s.replace(",", ".")
# If multiple dots exist, keep only the last one as decimal separator
if s.count(".") > 1:
parts = s.split(".")
s = "".join(parts[:-1]) + "." + parts[-1]
# Handle edge cases
if s in ("", ".", "-", "-."):
return ("0.00",)
# Handle leading minus
negative = s.startswith("-")
if negative:
s = s[1:]
# Convert to float and format to 2 decimal places
try:
value = float(s)
except ValueError:
value = 0.0
if negative:
value = -value
result = f"{value:.2f}"
return (result,)
+121
View File
@@ -0,0 +1,121 @@
import re
import numpy as np
from PIL import Image
class MaxValuePaddleOCR:
"""
A ComfyUI node that uses PaddleOCR to extract numbers from an image
and returns the largest numeric value found.
"""
def __init__(self):
self.ocr = None
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
},
"optional": {
"use_gpu": ("BOOLEAN", {"default": False}),
"lang": (["en", "ch", "japan", "korean", "french", "german"], {"default": "en"}),
}
}
RETURN_TYPES = ("FLOAT",)
RETURN_NAMES = ("max_value",)
FUNCTION = "extract_max_number"
CATEGORY = "image/text"
def _init_ocr(self, use_gpu=False, lang="en"):
"""Initialize PaddleOCR if not already done."""
if self.ocr is None:
from paddleocr import PaddleOCR
self.ocr = PaddleOCR(
use_angle_cls=True,
lang=lang,
use_gpu=use_gpu,
show_log=False
)
return self.ocr
def _extract_numbers(self, text):
"""
Extract all numeric values (integers and floats) from text.
Handles various number formats including negative numbers and decimals.
"""
# Pattern matches integers and floats, including negative numbers
# Examples: 123, -456, 3.14, -2.5, .5, -.5
pattern = r'-?\d+\.?\d*|-?\.\d+'
numbers = []
matches = re.findall(pattern, text)
for match in matches:
try:
# Try to convert to float (works for both int and float strings)
num = float(match)
numbers.append(num)
except ValueError:
continue
return numbers
def extract_max_number(self, image, use_gpu=False, lang="en"):
"""
Main function to extract the maximum number from an image.
Args:
image: ComfyUI IMAGE tensor (B, H, W, C) in range [0, 1]
use_gpu: Whether to use GPU for OCR
lang: Language for OCR recognition
Returns:
Tuple containing the maximum numeric value found, or 0.0 if none found
"""
# Initialize OCR
ocr = self._init_ocr(use_gpu=use_gpu, lang=lang)
# Convert ComfyUI image tensor to numpy array
# ComfyUI images are (B, H, W, C) with values in [0, 1]
if isinstance(image, np.ndarray):
img_array = image
else:
# Convert from torch tensor if needed
img_array = image.cpu().numpy()
# Handle batch dimension - process first image
if len(img_array.shape) == 4:
img_array = img_array[0]
# Convert from [0, 1] to [0, 255] and ensure uint8
img_array = (img_array * 255).astype(np.uint8)
# Convert to PIL Image then back to numpy for PaddleOCR
# PaddleOCR expects BGR or RGB numpy array
pil_image = Image.fromarray(img_array)
img_for_ocr = np.array(pil_image)
# Run OCR
result = ocr.ocr(img_for_ocr, cls=True)
# Extract all numbers from OCR results
all_numbers = []
if result and result[0]:
for line in result[0]:
if line and len(line) >= 2:
# line[1] contains (text, confidence)
text = line[1][0] if isinstance(line[1], (list, tuple)) else str(line[1])
numbers = self._extract_numbers(text)
all_numbers.extend(numbers)
# Return the maximum value, or 0.0 if no numbers found
if all_numbers:
max_value = max(all_numbers)
else:
max_value = 0.0
return (float(max_value),)