Files
WangPengxing-ComfyUI_WPX_Node/tools/image_process.py
T
2025-01-20 15:55:52 +08:00

93 lines
3.8 KiB
Python

import numpy as np
from PIL import Image
import os
import glob
import torch
def images_process(images, crop_image=False, padding=0):
"""
处理图片,返回处理后的图片
:param images: 图片路径or图片张量orPIL.Image.Image
:param crop_image: 是否进行正方形裁剪,默认False
:param padding: 裁剪时额外添加的边距,默认0
:return: 处理后的图片列表
"""
images_list = []
if isinstance(images, str):
# 如果传入的是文件夹路径,则遍历文件夹中的所有图片
if os.path.isdir(images):
images_files = glob.glob(os.path.join(images, '*')) # 图片路径列表
images_list = [Image.open(image).convert("RGBA") for image in images_files] # PIL.Image图片列表
else:
images_list.append(Image.open(images).convert("RGBA"))
elif isinstance(images, torch.Tensor):
# 将传入的张量转置为(B, H, W, C)
if images.shape[1] == 3 or images.shape[1] == 4:
images = images.permute(0, 2, 3, 1) # (B, H, W, C)
print("[DEBUG]传入的是张量,张量的形状, ", images.shape)
images_tensor = [images[i:i+1] for i in range(images.shape[0])] # 将每个批次作为独立的图片
# 遍历每张贴纸
for img_tensor in images_tensor:
# 假设输入张量是 (1, H, W, C) 格式,取第一维的1(即去掉批次维度)
img_tensor = img_tensor.squeeze(0) # 去掉批次维度,得到(C, H, W)格式
# 将张量转换为PIL图像
img_np = img_tensor.cpu().numpy() # 将张量转换为numpy数组
img_np = (img_np * 255).astype(np.uint8)
# 将numpy数组转换为图像
img = Image.fromarray(img_np)
# 加入列表容器
images_list.append(img)
elif isinstance(images, list):
for image in images:
if isinstance(image, str):
image = Image.open(image).convert("RGBA")
images_list.append(image)
elif isinstance(images, Image.Image):
images_list.append(images.convert("RGBA"))
else:
print("传入的参数类型错误,", type(images))
# 在返回之前添加裁剪处理
if crop_image:
cropped_images = []
for img in images_list:
# 获取图片的alpha通道
alpha = img.split()[-1]
# 获取非透明区域的边界框
bbox = alpha.getbbox()
if bbox:
left, top, right, bottom = bbox
# 计算边界框的宽度和高度
width = right - left
height = bottom - top
# 使用最大边长构建正方形
max_side = max(width, height) + 2 * padding
# 计算原图中心点
center_x = (left + right) // 2
center_y = (top + bottom) // 2
# 计算正方形裁剪区域
new_left = center_x - max_side // 2
new_top = center_y - max_side // 2
new_right = new_left + max_side
new_bottom = new_top + max_side
# 确保裁剪区域不超出图片范围
img_width, img_height = img.size
new_left = max(0, new_left)
new_top = max(0, new_top)
new_right = min(img_width, new_right)
new_bottom = min(img_height, new_bottom)
# 裁剪图片
cropped_img = img.crop((new_left, new_top, new_right, new_bottom))
cropped_images.append(cropped_img)
else:
# 如果没有非透明区域,直接添加原图
cropped_images.append(img)
return cropped_images
return images_list