mirror of
https://github.com/hanzoui/mixlab-nodes.git
synced 2026-10-30 20:48:06 +00:00
173 lines
5.0 KiB
Python
173 lines
5.0 KiB
Python
import torch
|
||
from PIL import Image, ImageOps, ImageSequence, ImageFile
|
||
from PIL.PngImagePlugin import PngInfo
|
||
|
||
import numpy as np
|
||
import os
|
||
import folder_paths
|
||
import node_helpers
|
||
import hashlib
|
||
|
||
# Tensor to PIL
|
||
def tensor2pil(image):
|
||
return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
|
||
|
||
# tensor 取hash值
|
||
def tensor_to_hash(tensor):
|
||
# 将 Tensor 转换为 NumPy 数组
|
||
np_array = tensor.cpu().numpy()
|
||
|
||
# 将 NumPy 数组转换为字节数据
|
||
byte_data = np_array.tobytes()
|
||
|
||
# 计算哈希值
|
||
hash_value = hashlib.md5(byte_data).hexdigest()
|
||
|
||
return hash_value
|
||
|
||
|
||
def create_temp_file(image):
|
||
output_dir = folder_paths.get_temp_directory()
|
||
|
||
(
|
||
full_output_folder,
|
||
filename,
|
||
counter,
|
||
subfolder,
|
||
_,
|
||
) = folder_paths.get_save_image_path('material', output_dir)
|
||
|
||
|
||
image=tensor2pil(image)
|
||
|
||
image_file = f"{filename}_{counter:05}.png"
|
||
|
||
image_path=os.path.join(full_output_folder, image_file)
|
||
|
||
image.save(image_path,compress_level=4)
|
||
|
||
return (image_path,[{
|
||
"filename": image_file,
|
||
"subfolder": subfolder,
|
||
"type": "temp"
|
||
}])
|
||
|
||
|
||
# image - tensor - 文件路径
|
||
# loadImage的方法( 文件路径 - image-mask )
|
||
class EditMask:
|
||
|
||
def __init__(self):
|
||
self.image_id = None
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(s):
|
||
return {"required":
|
||
{"image": ("IMAGE",), # 表示一个张量
|
||
|
||
},
|
||
|
||
"optional":{
|
||
"image_update": ("IMAGE_FILE",)
|
||
},
|
||
|
||
}
|
||
|
||
CATEGORY = "♾️Mixlab/Mask"
|
||
|
||
RETURN_TYPES = ("IMAGE", "MASK")
|
||
RETURN_NAMES = ("image", "mask")
|
||
|
||
FUNCTION = "edit"
|
||
|
||
OUTPUT_NODE = True
|
||
|
||
def edit(self, image,image_update=None):
|
||
|
||
# 根据image输入来判断是否是新的图片
|
||
if self.image_id==None:
|
||
self.image_id=tensor_to_hash(image)
|
||
image_update=None
|
||
else:
|
||
image_id=tensor_to_hash(image)
|
||
if image_id!=self.image_id:
|
||
image_update=None
|
||
self.image_id=image_id
|
||
|
||
|
||
image_path=None
|
||
# print('#image_update',self.image_id,image_update)
|
||
if image_update==None:
|
||
print('--')
|
||
else:
|
||
if 'images' in image_update:
|
||
images=image_update['images']
|
||
filename=images[0]['filename']
|
||
subfolder=images[0]['subfolder']
|
||
type=images[0]['type']
|
||
name, base_dir=folder_paths.annotated_filepath(filename)
|
||
if type.endswith("output"):
|
||
base_dir = folder_paths.get_output_directory()
|
||
elif type.endswith("input"):
|
||
base_dir = folder_paths.get_input_directory()
|
||
elif type.endswith("temp"):
|
||
base_dir = folder_paths.get_temp_directory()
|
||
#base_dir = folder_paths.get_input_directory()
|
||
# print(base_dir,subfolder, name)
|
||
image_path = os.path.join(base_dir,subfolder, name)
|
||
|
||
if image_path==None:
|
||
image_path,images=create_temp_file(image)
|
||
|
||
print('#image_path',os.path.exists(image_path),image_path)
|
||
# image_path = folder_paths.get_annotated_filepath(image) #文件名
|
||
|
||
if not os.path.exists(image_path):
|
||
image_path,images=create_temp_file(image)
|
||
|
||
|
||
img = node_helpers.pillow(Image.open, image_path)
|
||
|
||
output_images = []
|
||
output_masks = []
|
||
w, h = None, None
|
||
|
||
excluded_formats = ['MPO']
|
||
|
||
for i in ImageSequence.Iterator(img):
|
||
i = node_helpers.pillow(ImageOps.exif_transpose, i)
|
||
|
||
if i.mode == 'I':
|
||
i = i.point(lambda i: i * (1 / 255))
|
||
image = i.convert("RGB")
|
||
|
||
if len(output_images) == 0:
|
||
w = image.size[0]
|
||
h = image.size[1]
|
||
|
||
if image.size[0] != w or image.size[1] != h:
|
||
continue
|
||
|
||
image = np.array(image).astype(np.float32) / 255.0
|
||
image = torch.from_numpy(image)[None,]
|
||
if 'A' in i.getbands():
|
||
mask = np.array(i.getchannel('A')).astype(np.float32) / 255.0
|
||
mask = 1. - torch.from_numpy(mask)
|
||
else:
|
||
# 尺寸不对,需要按照image来
|
||
mask = torch.zeros((h, w), dtype=torch.float32, device="cpu")
|
||
|
||
output_images.append(image)
|
||
output_masks.append(mask.unsqueeze(0))
|
||
|
||
if len(output_images) > 1 and img.format not in excluded_formats:
|
||
output_image = torch.cat(output_images, dim=0)
|
||
output_mask = torch.cat(output_masks, dim=0)
|
||
else:
|
||
output_image = output_images[0]
|
||
output_mask = output_masks[0]
|
||
|
||
return {"ui":{"images": images},"result": (output_image, output_mask)}
|
||
|
||
# return (output_image, output_mask)
|