StupidGame's picture
Upload 1941 files
baa8e90
raw
history blame contribute delete
No virus
11.6 kB
# -*- coding: utf-8 -*-
from .categories import NodeCategories
from .shared import *
from .dreamtypes import *
class DreamImageAreaSampler:
NODE_NAME = "Sample Image Area as Palette"
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"samples": ("INT", {"default": 256, "min": 1, "max": 1024 * 4}),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"area": (["top-left", "top-center", "top-right",
"center-left", "center", "center-right",
"bottom-left", "bottom-center", "bottom-right"],)
},
}
CATEGORY = NodeCategories.IMAGE_COLORS
RETURN_TYPES = (RGBPalette.ID,)
RETURN_NAMES = ("palette",)
FUNCTION = "result"
@classmethod
def IS_CHANGED(cls, *values):
return ALWAYS_CHANGED_FLAG
def _get_pixel_area(self, img: DreamImage, area):
w = img.width
h = img.height
wpart = round(w / 3)
hpart = round(h / 3)
x0 = 0
x1 = wpart - 1
x2 = wpart
x3 = wpart + wpart - 1
x4 = wpart + wpart
x5 = w - 1
y0 = 0
y1 = hpart - 1
y2 = hpart
y3 = hpart + hpart - 1
y4 = hpart + hpart
y5 = h - 1
if area == "center":
return (x2, y2, x3, y3)
elif area == "top-center":
return (x2, y0, x3, y1)
elif area == "bottom-center":
return (x2, y4, x3, y5)
elif area == "center-left":
return (x0, y2, x1, y3)
elif area == "top-left":
return (x0, y0, x1, y1)
elif area == "bottom-left":
return (x0, y4, x1, y5)
elif area == "center-right":
return (x4, y2, x5, y3)
elif area == "top-right":
return (x4, y0, x5, y1)
elif area == "bottom-right":
return (x4, y4, x5, y5)
def result(self, image, samples, seed, area):
result = list()
r = random.Random()
r.seed(seed)
for data in image:
di = DreamImage(tensor_image=data)
area = self._get_pixel_area(di, area)
pixels = list()
for i in range(samples):
x = r.randint(area[0], area[2])
y = r.randint(area[1], area[3])
pixels.append(di.get_pixel(x, y))
result.append(RGBPalette(colors=pixels))
return (tuple(result),)
class DreamImageSampler:
NODE_NAME = "Sample Image as Palette"
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"samples": ("INT", {"default": 1024, "min": 1, "max": 1024 * 4}),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff})
},
}
CATEGORY = NodeCategories.IMAGE_COLORS
RETURN_TYPES = (RGBPalette.ID,)
RETURN_NAMES = ("palette",)
FUNCTION = "result"
@classmethod
def IS_CHANGED(cls, *values):
return ALWAYS_CHANGED_FLAG
def result(self, image, samples, seed):
result = list()
r = random.Random()
r.seed(seed)
for data in image:
di = DreamImage(tensor_image=data)
pixels = list()
for i in range(samples):
x = r.randint(0, di.width - 1)
y = r.randint(0, di.height - 1)
pixels.append(di.get_pixel(x, y))
result.append(RGBPalette(colors=pixels))
return (tuple(result),)
class DreamColorAlign:
NODE_NAME = "Palette Color Align"
@classmethod
def INPUT_TYPES(cls):
return {
"required": SharedTypes.palette | {
"target_align": (RGBPalette.ID,),
"alignment_factor": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 10.0, "step": 0.1}),
}
}
CATEGORY = NodeCategories.IMAGE_COLORS
RETURN_TYPES = (RGBPalette.ID,)
RETURN_NAMES = ("palette",)
FUNCTION = "result"
@classmethod
def IS_CHANGED(cls, *values):
return ALWAYS_CHANGED_FLAG
def result(self, palette: Tuple[RGBPalette], target_align: Tuple[RGBPalette], alignment_factor: float):
results = list()
def _limit(c):
return max(min(c, 255), 0)
for i in range(len(palette)):
p = palette[i]
t = target_align[i]
(_, _, r1, g1, b1) = p.analyze()
(_, _, r2, g2, b2) = t.analyze()
dr = (r2 - r1) * alignment_factor
dg = (g2 - g1) * alignment_factor
db = (b2 - b1) * alignment_factor
new_pixels = list()
for pixel in p:
r = _limit(round(pixel[0] + (255 * dr)))
g = _limit(round(pixel[1] + (255 * dg)))
b = _limit(round(pixel[1] + (255 * db)))
new_pixels.append((r, g, b))
results.append(RGBPalette(colors=new_pixels))
return (tuple(results),)
class DreamColorShift:
NODE_NAME = "Palette Color Shift"
@classmethod
def INPUT_TYPES(cls):
return {
"required": SharedTypes.palette | {
"red_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step": 0.1}),
"green_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step": 0.1}),
"blue_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step": 0.1}),
"fixed_brightness": (["yes", "no"],),
}
}
CATEGORY = NodeCategories.IMAGE_COLORS
RETURN_TYPES = (RGBPalette.ID,)
RETURN_NAMES = ("palette",)
FUNCTION = "result"
@classmethod
def IS_CHANGED(cls, *values):
return ALWAYS_CHANGED_FLAG
def result(self, palette, red_multiplier, green_multiplier, blue_multiplier, fixed_brightness):
results = list()
def _limit(c):
return max(min(c, 255), 0)
for p in palette:
new_pixels = list()
for pixel in p:
s = pixel[0] + pixel[1] + pixel[2]
r = _limit(round(pixel[0] * red_multiplier))
g = _limit(round(pixel[1] * green_multiplier))
b = _limit(round(pixel[2] * blue_multiplier))
if fixed_brightness == "yes":
brightness_factor = max(s, 1) / float(max(r + g + b, 1))
r = _limit(round(r * brightness_factor))
g = _limit(round(g * brightness_factor))
b = _limit(round(b * brightness_factor))
new_pixels.append((r, g, b))
results.append(RGBPalette(colors=new_pixels))
return (tuple(results),)
class DreamImageColorShift:
NODE_NAME = "Image Color Shift"
ICON = "๐Ÿ–ผ"
@classmethod
def INPUT_TYPES(cls):
return {
"required": {"image": ("IMAGE",),
"red_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0}),
"green_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0}),
"blue_multiplier": ("FLOAT", {"default": 1.0, "min": 0.0}),
},
}
CATEGORY = NodeCategories.IMAGE_COLORS
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = "result"
@classmethod
def IS_CHANGED(cls, *values):
return ALWAYS_CHANGED_FLAG
def result(self, image, red_multiplier, green_multiplier, blue_multiplier):
proc = DreamImageProcessor(inputs=image)
def recolor(im: DreamImage, *a, **args):
return (im.adjust_colors(red_multiplier, green_multiplier, blue_multiplier),)
return proc.process(recolor)
class DreamImageBrightness:
NODE_NAME = "Image Brightness Adjustment"
ICON = "โ˜ผ"
@classmethod
def INPUT_TYPES(cls):
return {
"required": {"image": ("IMAGE",),
"factor": ("FLOAT", {"default": 1.0, "min": 0.0}),
},
}
CATEGORY = NodeCategories.IMAGE_COLORS
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = "result"
@classmethod
def IS_CHANGED(cls, *values):
return ALWAYS_CHANGED_FLAG
def result(self, image, factor):
proc = DreamImageProcessor(inputs=image)
def change(im: DreamImage, *a, **args):
return (im.change_brightness(factor),)
return proc.process(change)
class DreamImageContrast:
NODE_NAME = "Image Contrast Adjustment"
ICON = "โ—"
@classmethod
def INPUT_TYPES(cls):
return {
"required": {"image": ("IMAGE",),
"factor": ("FLOAT", {"default": 1.0, "min": 0.0}),
},
}
CATEGORY = NodeCategories.IMAGE_COLORS
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = "result"
@classmethod
def IS_CHANGED(cls, *values):
return ALWAYS_CHANGED_FLAG
def result(self, image, factor):
proc = DreamImageProcessor(inputs=image)
def change(im: DreamImage, *a, **args):
return (im.change_contrast(factor),)
return proc.process(change)
class DreamComparePalette:
NODE_NAME = "Compare Palettes"
ICON = "๐Ÿ“Š"
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"a": (RGBPalette.ID,),
"b": (RGBPalette.ID,),
},
}
CATEGORY = NodeCategories.IMAGE_COLORS
RETURN_TYPES = ("FLOAT", "FLOAT", "FLOAT", "FLOAT")
RETURN_NAMES = (
"brightness_multiplier", "contrast_multiplier", "red_multiplier", "green_multiplier", "blue_multiplier")
FUNCTION = "result"
@classmethod
def IS_CHANGED(cls, *values):
return ALWAYS_CHANGED_FLAG
def result(self, a, b):
MIN_VALUE = 1 / 255.0
brightness = list()
contrasts = list()
reds = list()
greens = list()
blues = list()
for i in range(min(len(a), len(b))):
(bright, ctr, red, green, blue) = a[i].analyze()
(bright2, ctr2, red2, green2, blue2) = b[i].analyze()
brightness.append(bright2 / max(MIN_VALUE, bright))
contrasts.append(ctr2 / max(MIN_VALUE, ctr))
reds.append(red2 / max(MIN_VALUE, red))
greens.append(green2 / max(MIN_VALUE, green))
blues.append(blue2 / max(MIN_VALUE, blue))
n = len(brightness)
return (sum(brightness) / n, sum(contrasts) / n, sum(reds) / n,
sum(greens) / n, sum(blues) / n)
class DreamAnalyzePalette:
NODE_NAME = "Analyze Palette"
ICON = "๐Ÿ“Š"
@classmethod
def INPUT_TYPES(cls):
return {
"required": SharedTypes.palette
,
}
CATEGORY = NodeCategories.IMAGE_COLORS
RETURN_TYPES = ("FLOAT", "FLOAT", "FLOAT", "FLOAT", "FLOAT")
RETURN_NAMES = ("brightness", "contrast", "redness", "greenness", "blueness")
FUNCTION = "result"
@classmethod
def IS_CHANGED(cls, *values):
return ALWAYS_CHANGED_FLAG
def result(self, palette):
f = 1.0 / len(palette)
(w, c, r, g, b) = (0, 0, 0, 0, 0)
for p in palette:
(brightness, contrast, red, green, blue) = p.analyze()
w += brightness
c += contrast
r += red
g += green
b += blue
return w * f, c * f, r * f, g * f, b * f