Skip to content

Commit 873039b

Browse files
committed
modulation
1 parent ef61b75 commit 873039b

File tree

3 files changed

+63
-21
lines changed

3 files changed

+63
-21
lines changed

__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from .nodes.image_utility import ImagesIndexNode
3434
from .nodes.image_utility import ImagesCatNode
3535
from .nodes.image_utility import ImagesInfoNode
36-
from .nodes.image_utility import DitherNode
36+
from .nodes.image_utility import ModulationNode
3737

3838

3939
from .nodes.utility import PrintAnyNode
@@ -104,7 +104,7 @@
104104
"ImagesInfoNode": ImagesInfoNode,
105105
"Base64ToImageNode": Base64ToImageNode,
106106
"ASCIICharNode": ASCIICharNode,
107-
"DitherNode": DitherNode,
107+
"ModulationNode": ModulationNode,
108108
}
109109

110110
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -156,7 +156,7 @@
156156
"ImagesCatNode": "Images Cat",
157157
"ImagesInfoNode": "Images Info",
158158
"ASCIICharNode": "ASCII Art Text",
159-
"DitherNode": "Dither",
159+
"ModulationNode": "Modulation",
160160
}
161161

162162

nodes/image_utility.py

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ def INPUT_TYPES(cls):
212212
"resize_to": (IO.INT, {"default": 1024, "max": 4096}),
213213
"side": (["shortest", "longest", "width", "height"], {"default": "longest"}),
214214
"interpolation": (["lanczos", "nearest", "bilinear", "bicubic", "area", "nearest-exact"], {"default": "lanczos"}),
215+
"divisible_by_2": (IO.BOOLEAN, {"default": False}),
215216
}
216217
}
217218

@@ -221,7 +222,7 @@ def INPUT_TYPES(cls):
221222
OUTPUT_NODE = True
222223
CATEGORY = "Fair/image"
223224

224-
def node_function(self, image, resize_to, side, interpolation):
225+
def node_function(self, image, resize_to, side, interpolation, divisible_by_2):
225226
image = image.movedim(-1, 1)
226227

227228
image_height, image_width = image.shape[-2:]
@@ -246,6 +247,10 @@ def node_function(self, image, resize_to, side, interpolation):
246247
width = int(width)
247248
height = int(height)
248249

250+
if divisible_by_2:
251+
width = width - width % 2
252+
height = height - height % 2
253+
249254
image = comfy.utils.common_upscale(image, width, height, interpolation, "center")
250255
image = image.movedim(1, -1)
251256

@@ -815,7 +820,7 @@ def node_function(self, images):
815820
return (width, height, length)
816821

817822

818-
class DitherNode:
823+
class ModulationNode:
819824
def __init__(self):
820825
pass
821826

@@ -824,7 +829,8 @@ def INPUT_TYPES(cls):
824829
return {
825830
"required": {
826831
"images": (IO.IMAGE, {"defaultInput": True}),
827-
"dither": (["Modulation", "Floyd Steinberg", "Halftone"], {"default": "Modulation"}),
832+
"direction": (["up_to_down", "down_to_up", "left_to_right", "right_to_left"], {"default": "up_to_down"}),
833+
"speed": (IO.FLOAT, {"default": 0.01, "step": 0.01}),
828834
}
829835
}
830836

@@ -852,36 +858,72 @@ def floyd_steinberg(self, image):
852858
image[y + 1, x - 1] += error * 0.1875 # left, down, 3 / 16
853859
return image
854860

855-
def modulation(self, image):
861+
def modulation(self, image, offset, direction, speed):
856862
h, w = image.shape
857-
for y in range(h):
863+
864+
if direction == "up_to_down":
858865
for x in range(w):
859-
old = image[y, x]
860-
new = np.round(old)
861-
image[y, x] = new
862-
error = old - new
863-
# precomputing the constants helps
864-
if x + 1 < w:
865-
image[y, x + 1] += error * 1 # right
866+
for y in range(h):
867+
old = image[y, x]
868+
new = np.round(old)
869+
image[y, x] = new
870+
error = old - new
871+
if y == 0:
872+
error -= offset * speed
873+
if y + 1 < h:
874+
image[y + 1, x] += error
875+
elif direction == "down_to_up":
876+
for x in range(w):
877+
for y in range(h - 1, -1, -1):
878+
old = image[y, x]
879+
new = np.round(old)
880+
image[y, x] = new
881+
error = old - new
882+
if y == h - 1:
883+
error -= offset * speed
884+
if y - 1 >= 0:
885+
image[y - 1, x] += error
886+
elif direction == "left_to_right":
887+
for y in range(h):
888+
for x in range(w):
889+
old = image[y, x]
890+
new = np.round(old)
891+
image[y, x] = new
892+
error = old - new
893+
if x == 0:
894+
error -= offset * speed
895+
if x + 1 < w:
896+
image[y, x + 1] += error
897+
elif direction == "right_to_left":
898+
for y in range(h):
899+
for x in range(w - 1, -1, -1):
900+
old = image[y, x]
901+
new = np.round(old)
902+
image[y, x] = new
903+
error = old - new
904+
if x == w - 1:
905+
error -= offset * speed
906+
if x - 1 >= 0:
907+
image[y, x - 1] += error
908+
866909
return image
867910

868-
def node_function(self, images, dither):
911+
def node_function(self, images, direction, speed):
869912
out_images = []
870913

871914
progress_counter = 0
872915
progress_total = images.shape[0]
873916
progress_bar = ProgressBar(progress_total)
874917

918+
index = 0
875919
for image in images:
876920
pil = tensor_to_pil(image).convert("L")
877921
img_np = pil_to_np(pil)
878-
if dither == "Floyd Steinberg":
879-
img_np = self.floyd_steinberg(img_np)
880-
elif dither == "Modulation":
881-
img_np = self.modulation(img_np)
922+
img_np = self.modulation(img_np, index, direction, speed)
882923
pil = np_to_pil(img_np).convert("RGB")
883924
image = pil_to_tensor(pil)
884925
out_images.append(image)
926+
index += 1
885927

886928
progress_counter += 1
887929
progress_bar.update_absolute(progress_counter, progress_total)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Python Script
6363
6464
Load LoRA Dual
6565
"""
66-
version = "1.0.72"
66+
version = "1.0.73"
6767
license = { file = "LICENSE" }
6868
dependencies = [
6969
"googletrans",

0 commit comments

Comments
 (0)