Skip to content

Commit

Permalink
color match histogram mode deprecated in favor of gradient map
Browse files Browse the repository at this point in the history
add HTTPS support for StreamWriter
custom GLSL shaders removed from node_list parse
  • Loading branch information
Amorano committed Aug 13, 2024
1 parent 55e02e1 commit b466222
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 22 deletions.
21 changes: 13 additions & 8 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ class Lexicon(metaclass=LexiconMeta):
G = '🟩', "Green"
GAMMA = '🔆', "Gamma"
GI = '💚', "Green Channel"
GLSL_CUSTOM = '🧙🏽‍♀️', "User GLSL Shader"
GLSL_INTERNAL = '🧙🏽', "Internal GLSL Shader"
GRADIENT = '🇲🇺', "Gradient"
H = '🇭', "Hue"
HI = 'HI', "High / Top of range"
Expand Down Expand Up @@ -877,16 +879,16 @@ def __init__(self, *arg, **kw) -> None:
JOV_IGNORE_NODE = []

node_count = 0
for f in (ROOT / 'core').iterdir():
if f.suffix != ".py" or f.stem.startswith('_'):
for fname in (ROOT / 'core').iterdir():
if fname.suffix != ".py" or fname.stem.startswith('_'):
continue
if f.stem in JOV_IGNORE_NODE or f.stem+'.py' in JOV_IGNORE_NODE:
logger.warning(f"💀 [IGNORED] Jovimetrix.core.{f.stem}")
if fname.stem in JOV_IGNORE_NODE or fname.stem+'.py' in JOV_IGNORE_NODE:
logger.warning(f"💀 [IGNORED] Jovimetrix.core.{fname.stem}")
continue
try:
module = importlib.import_module(f"Jovimetrix.core.{f.stem}")
module = importlib.import_module(f"Jovimetrix.core.{fname.stem}")
except Exception as e:
logger.warning(f"module failed {f}")
logger.warning(f"module failed {fname}")
logger.warning(str(e))
continue

Expand All @@ -912,8 +914,11 @@ def __init__(self, *arg, **kw) -> None:
else:
Session.CLASS_MAPPINGS[name] = class_object

desc = class_object.DESCRIPTION if hasattr(class_object, 'DESCRIPTION') else ""
NODE_LIST_MAP[name] = desc.split('.')[0].strip('\n')
if not name.endswith(Lexicon.GLSL_CUSTOM):
desc = class_object.DESCRIPTION if hasattr(class_object, 'DESCRIPTION') else ""
NODE_LIST_MAP[name] = desc.split('.')[0].strip('\n')
else:
logger.debug(f"customs {name}")
node_count += 1

logger.info(f"✅ {module.__name__}")
Expand Down
14 changes: 5 additions & 9 deletions core/compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
class EnumColorMatchMode(Enum):
REINHARD = 30
LUT = 10
HISTOGRAM = 20
# HISTOGRAM = 20

class EnumColorMatchMap(Enum):
USER_MAP = 0
Expand Down Expand Up @@ -335,7 +335,7 @@ class ColorMatchNode(JOVImageNode):
NAME = "COLOR MATCH (JOV) 💞"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
DESCRIPTION = """
Adjust the color scheme of one image to match another with the Color Match Node. Choose from various color matching modes, including LUT, Histogram, and Reinhard. You can specify options like color maps, the number of colors, and whether to flip or invert the images. This node allows for the creation of seamless and cohesive visuals, making it ideal for texture work or masking in motion graphics and design projects.
Adjust the color scheme of one image to match another with the Color Match Node. Choose from various color matching LUTs or Reinhard matching. You can specify a custom user color maps, the number of colors, and whether to flip or invert the images.
"""

@classmethod
Expand Down Expand Up @@ -385,7 +385,7 @@ def run(self, **kw) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
if pA.ndim == 3 and pA.shape[2] == 4:
mask = image_mask(pA)

h, w = pA.shape[:2]
# h, w = pA.shape[:2]
if pB is None:
pB = channel_solid(chan=EnumImageType.BGR)
else:
Expand All @@ -399,21 +399,16 @@ def run(self, **kw) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
pB = None
colormap = EnumColorMap[colormap]
pA = color_match_lut(pA, colormap.value, pB, num_colors)
case EnumColorMatchMode.HISTOGRAM:
pB = image_scalefit(pB, w, h, EnumScaleMode.CROP)
pB = image_scalefit(pB, w, h, EnumScaleMode.MATTE)
pA = color_match_histogram(pA, pB)

case EnumColorMatchMode.REINHARD:
pA = color_match_reinhard(pA, pB)


if invert == True:
pA = image_invert(pA, 1)

logger.debug(mask)
if mask is not None:
pA = image_mask_add(pA, mask)
logger.debug(pA.shape)

images.append(cv2tensor_full(pA, matte))
pbar.update_absolute(idx)
Expand Down Expand Up @@ -659,6 +654,7 @@ def run(self, **kw) -> torch.Tensor:
pbar = ProgressBar(len(params))
for idx, (pA, gradient, flip, mode, sample, wihi, matte) in enumerate(params):
pA = channel_solid(chan=EnumImageType.BGR) if pA is None else tensor2cv(pA)
mask = None
if pA.ndim == 3 and pA.shape[2] == 4:
mask = image_mask(pA)

Expand Down
4 changes: 2 additions & 2 deletions core/create_glsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,10 +268,10 @@ def import_dynamic() -> Tuple[str,...]:
class_name = name.title().replace(' ', '_')
class_name = f'GLSLNode_{class_name}'

emoji = '🧙🏽‍♀️'
emoji = Lexicon.GLSL_CUSTOM
sort_order = sort
if fname.startswith(root):
emoji = '🧙🏽'
emoji = Lexicon.GLSL_INTERNAL
sort_order -= 10000

category = GLSLNodeDynamic.CATEGORY
Expand Down
1 change: 1 addition & 0 deletions core/device_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ def __init__(self, *arg, **kw) -> None:
super().__init__(*arg, **kw)
self.__route = ""
self.__unique = uuid.uuid4()

self.__device = StreamManager().capture(self.__unique, static=True)

def run(self, **kw) -> Tuple[torch.Tensor]:
Expand Down
2 changes: 0 additions & 2 deletions node_list.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
"FLATTEN (JOV) \u2b07\ufe0f": "Combine multiple input images into a single image by summing their pixel values",
"GLSL (JOV) \ud83c\udf69": "Execute custom GLSL (OpenGL Shading Language) fragment shaders to generate images or apply effects",
"GLSL BLEND LINEAR (JOV) \ud83e\uddd9\ud83c\udffd": "Simple linear blend between two images",
"GLSL FILTER RANGE (JOV) \ud83e\uddd9\ud83c\udffd\u200d\u2640\ufe0f": "Select pixels from start color through end color",
"GLSL GRAYSCALE (JOV) \ud83e\uddd9\ud83c\udffd": "Convert input to grayscale",
"GLSL HSV ADJUST (JOV) \ud83e\uddd9\ud83c\udffd": "HSV ADJUST",
"GLSL HSV-2-LAB (JOV) \ud83e\uddd9\ud83c\udffd": "Convert HSV input to LAB",
"GLSL HSV-2-RGB (JOV) \ud83e\uddd9\ud83c\udffd": "Convert HSV input to RGB",
"GLSL LAB-2-HSV (JOV) \ud83e\uddd9\ud83c\udffd": "Convert LAB color space to HSV",
Expand Down
19 changes: 18 additions & 1 deletion sup/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""

import os
import ssl
import sys
import json
import time
Expand All @@ -20,6 +21,8 @@
import numpy as np
from PIL import Image, ImageGrab

from comfy.cli_args import args as cmd_args

from loguru import logger

# SPOUT SUPPORT
Expand Down Expand Up @@ -557,14 +560,28 @@ def __init__(self, host: str='', port: int=JOV_STREAM_PORT) -> None:
self.__host = host
self.__port = port
self.__address = (self.__host, self.__port)
self.__tls_keyfile = cmd_args.tls_keyfile
self.__tls_certfile = cmd_args.tls_certfile
self.__thread_server = threading.Thread(target=self.__server, daemon=True)
self.__thread_server.start()
self.__thread_capture = threading.Thread(target=self.__capture, daemon=True)
self.__thread_capture.start()
logger.info("STARTED")

def __server(self) -> None:
httpd = ThreadingHTTPServer(self.__address, lambda *args: StreamingHandler(StreamingServer.OUT, *args))
handler = lambda *args: StreamingHandler(StreamingServer.OUT, *args)
httpd = ThreadingHTTPServer(self.__address, handler)

if self.__tls_keyfile and self.__tls_certfile:
# HTTPS mode
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(self.__tls_certfile, self.__tls_keyfile)
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
logger.info(f"HTTPS server {self.__address}")
else:
# HTTP mode
logger.info(f"HTTP server {self.__address}")

while True:
httpd.handle_request()

Expand Down

0 comments on commit b466222

Please sign in to comment.