Files
AbyssBadger0-ComfyUI_Badger…/__init__.py
T

360 lines
8.9 KiB
Python

import math
from PIL import Image
import numpy as np
import torch
import comfy.utils
def getImageSize(IMAGE) -> tuple[int, int]:
samples = IMAGE.movedim(-1, 1)
size = samples.shape[3], samples.shape[2]
return size
def tensorToImg(imageTensor):
imaget = imageTensor[0]
i = 255. * imaget.cpu().numpy()
img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
return img
def imgToTensor(img):
image = np.array(img).astype(np.float32) / 255.0
imaget = torch.from_numpy(image)[None,]
return imaget
class ImageOverlap:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"base_image": ("IMAGE",),
"additional_image": ("IMAGE",),
"x": ("INT", {
"default": 0,
"min": 0,
"max": 4096,
"step": 1,
"display": "number"
}),
"y": ("INT", {
"default": 0,
"min": 0,
"max": 4096,
"step": 1,
"display": "number"
}),
},
}
RETURN_TYPES = ("IMAGE",)
# RETURN_NAMES = ("image_output_name",)
FUNCTION = "overlap"
# OUTPUT_NODE = False
CATEGORY = "badger"
def overlap(self, base_image, additional_image, x, y):
b_image = tensorToImg(base_image)
a_image = tensorToImg(additional_image)
b_image.paste(a_image, (x, y))
o_image = imgToTensor(b_image)
return (o_image,)
class FloatToInt:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"float": ("FLOAT", {
"default": 1.0,
"min": 0.0,
"max": 4096.0,
"step": 0.01,
"round": 0.01,
"display": "number"})
},
}
RETURN_TYPES = ("INT",)
# RETURN_NAMES = ("image_output_name",)
FUNCTION = "floatToInt"
# OUTPUT_NODE = False
CATEGORY = "badger"
def floatToInt(self, float):
return (round(float),)
class IntToString:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"int": ("INT", {
"default": 0,
"min": 0,
"max": 4096,
"step": 1,
"display": "number"
})
},
}
RETURN_TYPES = ("STRING",)
# RETURN_NAMES = ("image_output_name",)
FUNCTION = "intToString"
# OUTPUT_NODE = False
CATEGORY = "badger"
def intToString(self, int):
return (str(int),)
class FloatToString:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"float": ("FLOAT", {
"default": 1.0,
"min": 0.0,
"max": 10.0,
"step": 0.00001,
"round": False,
"display": "number"})
},
}
RETURN_TYPES = ("STRING",)
# RETURN_NAMES = ("image_output_name",)
FUNCTION = "floatToString"
# OUTPUT_NODE = False
CATEGORY = "badger"
def floatToString(self, float):
return (str(float),)
class ImageNormalization:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"width": ("INT", {
"default": 1.0,
"min": 0.0,
"max": 4096.0,
"step": 0.01,
"round": 0.01,
"display": "number"}),
"height": ("INT", {
"default": 1.0,
"min": 0.0,
"max": 4096.0,
"step": 0.01,
"round": 0.01,
"display": "number"}),
"target_width": ("INT", {
"default": 1.0,
"min": 0.0,
"max": 4096.0,
"step": 0.01,
"round": 0.01,
"display": "number"}),
"target_height": ("INT", {
"default": 1.0,
"min": 0.0,
"max": 4096.0,
"step": 0.01,
"round": 0.01,
"display": "number"})
},
}
RETURN_TYPES = ("INT", "INT", "INT", "INT", "INT", "INT",)
RETURN_NAMES = ("new_width", "new_height", "top", "left", "bottom", "right")
FUNCTION = "imageNormalization"
# OUTPUT_NODE = False
CATEGORY = "badger"
def imageNormalization(self, width, height, target_width, target_height):
o_ratio = width/height
ratio = target_width/target_height
top = 0
left = 0
bottom = 0
right = 0
nw = 0
nh = 0
# 原图比期望尺寸更扁,对齐宽,计算高,补上下
if(o_ratio>=ratio):
upratio = target_width/width
nw = target_width
nh = round(height*upratio)
hdiff = target_height - nh
top = math.floor(hdiff/2)
bottom = math.ceil(hdiff/2)
else:
upratio = target_height/height
nw = round(width*upratio)
nh = target_height
wdiff = target_width - nw
left = math.floor(wdiff/2)
right = math.ceil(wdiff/2)
return (nw, nh, top, left, bottom, right,)
class ImageScaleToSide:
upscale_methods = ["nearest-exact", "bilinear", "area"]
crop_methods = ["disabled", "center"]
def __init__(self) -> None:
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"side_length": ("INT", {
"default": 1,
"min": 1,
"max": 4096,
"step": 1,
"display": "number"
}),
"side": (["Longest", "Shortest", "Width", "Height"],),
"upscale_method": (cls.upscale_methods,),
"crop": (cls.crop_methods,)}}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "imageUpscaleToSide"
CATEGORY = "badger"
def imageUpscaleToSide(self, image, upscale_method, side_length: int, side: str, crop):
samples = image.movedim(-1, 1)
size = getImageSize(image)
width_B = int(size[0])
height_B = int(size[1])
width = width_B
height = height_B
def determineSide(_side: str) -> tuple[int, int]:
width, height = 0, 0
if _side == "Width":
heigh_ratio = height_B / width_B
width = side_length
height = heigh_ratio * width
elif _side == "Height":
width_ratio = width_B / height_B
height = side_length
width = width_ratio * height
return width, height
if side == "Longest":
if width > height:
width, height = determineSide("Width")
else:
width, height = determineSide("Height")
elif side == "Shortest":
if width < height:
width, height = determineSide("Width")
else:
width, height = determineSide("Height")
else:
width, height = determineSide(side)
width = math.ceil(width)
height = math.ceil(height)
cls = comfy.utils.common_upscale(samples, width, height, upscale_method, crop)
cls = cls.movedim(1, -1)
return (cls,)
class NovelToFizz:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {"required": {"text": ("STRING", {"multiline": True})}}
RETURN_TYPES = ("STRING", "INT",)
FUNCTION = "novelToFizz"
CATEGORY = "badger"
def novelToFizz(self, text):
textA = text.split("\n")
lines = 0
outText = ""
for line in textA:
if(len(line)>0):
line = "\""+str(lines)+"\":\""+line+"\",\n"
lines = lines+1
outText = outText+line
outText = outText[:-2]
return (outText, lines, )
NODE_CLASS_MAPPINGS = {
"ImageOverlap-badger": ImageOverlap,
"FloatToInt-badger": FloatToInt,
"IntToString-badger": IntToString,
"FloatToString-badger": FloatToString,
"ImageNormalization-badger": ImageNormalization,
"ImageScaleToSide-badger": ImageScaleToSide,
"NovelToFizz-badger": NovelToFizz
}
NODE_DISPLAY_NAME_MAPPINGS = {
"ImageOverlap": "Example test"
}