Added some random things.

Nothing major.
This commit is contained in:
TeaCrab
2023-11-08 17:36:32 -05:00
parent 1b0d0d29ce
commit bf0aaa80ad
5 changed files with 243 additions and 11 deletions
+15
View File
@@ -0,0 +1,15 @@
{
"cSpell.enabled": true,
"cSpell.words": [
"alfault",
"byfault",
"debouncer",
"fclamp",
"hlsa",
"iclamp",
"ispowof",
"nparray",
"NYBL",
"yiqa"
]
}
+3
View File
@@ -0,0 +1,3 @@
@echo off
python _test.py
+176 -1
View File
@@ -1,5 +1,16 @@
import regex_spm, re, code
import numpy as np
from math import ceil, floor, log
from enum import Enum
from colorsys import (
rgb_to_hls,
rgb_to_hsv,
rgb_to_yiq,
hls_to_rgb,
hsv_to_rgb,
yiq_to_rgb,
)
debouncer = set()
@@ -41,3 +52,167 @@ def pixel_approx(primary, secondary, total=1024, ratio=1.0,
primary, secondary = pixel_approx(primary, secondary, total, ratio, threshold, _inc, False)
return (int(primary), int(secondary))
class RE:
HEX = re.compile(r"^\#[\da-fA-F]{1,8}$", re.IGNORECASE)
RGB = re.compile(r"^rgba?\s+(?:\d{1,3}[, ](?=\d)|\d{1,3}(?=$)){1,4}$", re.IGNORECASE)
HSV = re.compile(r"^hsva?\s+(?:\d{1,3}[, ](?=\d)|\d{1,3}(?=$)){1,4}$", re.IGNORECASE)
HLS = re.compile(r"^hlsa?\s+(?:\d{1,3}[, ](?=\d)|\d{1,3}(?=$)){1,4}$", re.IGNORECASE)
YIQ = re.compile(r"^yiqa?\s+(?:\d{1,3}[, ](?=\d)|\d{1,3}(?=$)){1,4}$", re.IGNORECASE)
class color_format_constant(Enum):
HEX,RGB,HSV,HLS,YIQ = range(5)
C = color_format_constant
def partition(array, step=2, indices=None):
if not indices: indices = np.array(range(len(array) // step))*2
return [array[i:i+step] for i in tuple(indices)]
def ispowof(value:int, exp=2):
return ceil(log(value, 2)) == floor(log(value, 2))
def iclamp(value:int, low=0, high=255) -> int:
return int(max(min(value, high), low))
def fclamp(value:float, low=0.0, high=1.0) -> float:
return float(max(min(value, high), low))
def baser(value:int) -> int:
'''
Convert a NYBL integer (0~16) into a BYTE integer (0~255)
Absolutely no error proofing whatsoever.
'''
return int(value * 16 + value)
def byte(value:float) -> int:
'''
Convert FLOAT scaler value to BYTE integer (0~255)
Absolutely no error proofing whatsoever.
'''
return iclamp(round(fclamp(value) * 255))
def scale(value: int) -> float:
'''
Convert a BYTE integer (0~255) to a FLOAT scaler (0.0~1.0)
Absolutely no error proofing whatsoever.
'''
return iclamp(value) / 255
def normalize(nparray, low=0.0, high=1.0):
return np.array([(((i - min(nparray)) * (high - low)) / (max(nparray) - min(nparray))) + low for i in nparray])
class Color():
default = C.HEX
alfault = False
byfault = False
def __init__(self, color="#0", style=None):
if isinstance(color, type(self)):
self.RGBA = color.RGBA
elif isinstance(color, type(tuple)):
match len(color):
case 1:
self.RGBA = color * 4
case 2:
self.RGBA = (color[0],) * 3 + (color[1],)
case 3:
self.RGBA = color + (1.0,)
case 4:
self.RGBA = color
case _:
self.RGBA = color[:4]
elif isinstance(color, str):
match regex_spm.fullmatch_in(color):
case RE.HEX:
_color = color.lstrip('#')
if not _color: print(f"Unhandled Case - {color}"); self.RGBA = self.fallback()
match len(_color):
case 1:
self.RGBA = (scale(baser(int(_color, 16))),) * 3 + (1.0,)
case 2:
self.RGBA = (scale(int(_color, 16)),) * 3 + (1.0,)
case 3:
self.RGBA = tuple(scale(baser(int(e, 16))) for e in _color) + (1.0,)
case 4:
self.RGBA = tuple(scale(baser(int(e, 16))) for e in _color)
case 6:
# _Color needs to be sliced in 2 char
self.RGBA = tuple(scale(int(e, 16)) for e in partition(_color)) + (1.0,)
case 8:
# _Color needs to be sliced in 2 char
self.RGBA = tuple(scale(int(e, 16)) for e in partition(_color))
case _:
print(f"Unhandled Case - {color}")
self.RGBA = self.fallback()
case RE.RGB:
_color = re.split(r" |,", color)
print(_color)
match len(_color[1:]):
case 1:
self.RGBA = tuple(scale(_color[1])) * 3 + (1.0,)
case 2:
self.RGBA = tuple(scale(_color[1])) * 3 + tuple(scale(_color[2]))
case 3:
self.RGBA = tuple(scale(int(e)) for e in _color[1:]) + (1.0,)
case 4:
self.RGBA = tuple(scale(int(e)) for e in _color[1:])
case _:
print(f"Unhandled Case - {color}")
self.RGBA = self.fallback()
case _:
print(f"Unhandled Case - {color}")
return None
else:
print(f"Unhandled Case - {color}")
return None
def __str__(self, form=default, alpha=alfault, byte=byfault):
_result = None
match form:
case C.RGB:
_result = self.RGBA
case C.HSV:
_result = self.hsv()
case C.HLS:
_result = self.hls()
case C.YIQ:
_result = self.yiq()
case _:
return self.hex() if alpha else self.hex()[:-2]
if byte: _result = (f"{byte(e):3d}" for e in _result)
else: _result = (f"{round(e, 3):.3f}" for e in _result)
if alpha: _result = _result[:3]
return f'({",".join(_result)})'
def __repr__(self, form=default):
match form:
case C.RGB:
return self.RGBA
case C.HSV:
return self.hsv()
case C.HLS:
return self.hls()
case C.YIQ:
return self.yiq()
case _:
return self.hex()
def fallback(self):
try: return self.RGBA
except: return (0.0, 0.0, 0.0, 1.0)
def hex(self):
R, G, B, A = (byte(e) for e in self.RGBA)
return f"#{R:02x}{G:02x}{B:02x}{A:02x}"
def hls(self):
R, G, B, A = self.RGBA
return rgb_to_hls(R, G, B) + (A,)
def hsv(self):
R, G, B, A = self.RGBA
return rgb_to_hsv(R, G, B) + (A,)
def yiq(self):
R, G, B, A = self.RGBA
return rgb_to_yiq(R, G, B) + (A,)
+4
View File
@@ -0,0 +1,4 @@
import code
from _func import *
code.interact(local=locals())
+45 -10
View File
@@ -1,10 +1,12 @@
import os, torch
import os, torch, random
import numpy as np
import comfy.utils
from colorsys import rgb_to_hsv, hsv_to_rgb
from kornia.enhance import equalize_clahe
from ._func import pixel_approx, po2
# from .isnet import dis_process
from ._func import pixel_approx, po2, Color, byte
from .isnet import dis_process
from PIL import Image
class EqualizeCLAHE:
@@ -13,12 +15,10 @@ class EqualizeCLAHE:
return {
"required": {
"image": ("IMAGE", ),
"size": ("TUPLE", {"default": (1024, 1024)}),
"clip_limit": ("FLOAT", {"default": 64, "min": 0.0, "max": 255, "step": 0.1}),
"grid_size": ("INT", {"default": 8, "min": 1, "max": 64, "step": 1}),
},
"optional": {
"size": ("TUPLE", {"default": (1024, 1024)}),
}
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "equalize"
@@ -75,12 +75,10 @@ class ImageResize:
return {
"required": {
"image": ("IMAGE",),
"size": ("TUPLE", {"default": (1024, 1024)}),
"width": ("INT", {"default": 1024, "min": 512, "max": 4096, "step": 32}),
"height": ("INT", {"default": 1024, "min": 512, "max": 4096, "step": 32}),
},
"optional": {
"size": ("TUPLE", {"default": (1024, 1024)}),
}
}
RETURN_TYPES = ("IMAGE",)
@@ -120,6 +118,42 @@ class ImageScale:
return (result,)
class RandomColorFill():
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"color": ("STRING", {"default": '#7f7f7fff'}),
"hue_range": ("FLOAT", {"default": 0.005}),
"sat_range": ("FLOAT", {"default": 0.005}),
"val_range": ("FLOAT", {"default": 0.005})
},
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "randomize"
CATEGORY = "TeaNodes/Input"
def randomize(self, image, color, hue_range, sat_range, val_range):
h, s, v, _ = Color(color).hsv()
h += hue_range * (random.random() - 0.5)
s += sat_range * (random.random() - 0.5)
v += val_range * (random.random() - 0.5)
color_rgba = Color()
color_rgba.RGBA = hsv_to_rgb(h, s, v) + (1.0,)
print(f"Random Color:\t{color_rgba.hex()}")
height, width = image.shape[1:3]
_color = tuple(byte(e) for e in color_rgba.RGBA)
_image = Image.new('RGBA', (width, height), _color)
_image = np.array(_image.convert('RGBA')).astype(np.float32) / 255.0
result = torch.from_numpy(_image).unsqueeze(0)
return (result,)
class ColorFill():
@classmethod
def INPUT_TYPES(cls):
@@ -192,5 +226,6 @@ NODE_CLASS_MAPPINGS = {
"TC_ImageResize": ImageResize,
"TC_ImageScale": ImageScale,
"TC_ColorFill": ColorFill,
# "TC_MaskBG_DIS": MaskBG_DIS,
"TC_RandomColorFill": RandomColorFill,
"TC_MaskBG_DIS": MaskBG_DIS,
}