@@ -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 )
0 commit comments