69 lines
2.4 KiB
Python
69 lines
2.4 KiB
Python
"""Image and tensor conversion helpers shared by LayerForge endpoints."""
|
|
|
|
import numpy as np
|
|
from PIL import Image
|
|
from torchvision import transforms
|
|
|
|
from .image_serialization import data_url_to_pil, pil_to_data_url
|
|
from .node import log
|
|
|
|
|
|
def convert_base64_to_tensor(base64_str):
|
|
"""Convert a data-URL image into a BCHW tensor and optional alpha tensor."""
|
|
try:
|
|
img = data_url_to_pil(base64_str)
|
|
|
|
has_alpha = img.mode == "RGBA"
|
|
alpha = None
|
|
if has_alpha:
|
|
alpha = img.split()[3]
|
|
background = Image.new("RGB", img.size, (255, 255, 255))
|
|
background.paste(img, mask=alpha)
|
|
img = background
|
|
elif img.mode != "RGB":
|
|
img = img.convert("RGB")
|
|
|
|
img_tensor = transforms.ToTensor()(img).unsqueeze(0)
|
|
if has_alpha:
|
|
alpha_tensor = transforms.ToTensor()(alpha).unsqueeze(0)
|
|
return img_tensor, alpha_tensor
|
|
|
|
return img_tensor, None
|
|
except Exception as error:
|
|
log.error(f"Error in convert_base64_to_tensor: {error}")
|
|
raise
|
|
|
|
|
|
def convert_tensor_to_base64(tensor, alpha_mask=None, original_alpha=None):
|
|
"""Convert a tensor to a PNG data URL, optionally preserving alpha."""
|
|
try:
|
|
tensor = tensor.cpu()
|
|
|
|
if tensor.dim() == 4:
|
|
tensor = tensor.squeeze(0)
|
|
if tensor.dim() == 3 and tensor.shape[0] in [1, 3]:
|
|
tensor = tensor.permute(1, 2, 0)
|
|
|
|
img_array = (tensor.numpy() * 255).astype(np.uint8)
|
|
|
|
if alpha_mask is not None and original_alpha is not None:
|
|
alpha_mask = (alpha_mask.cpu().squeeze().numpy() * 255).astype(np.uint8)
|
|
original_alpha = (original_alpha.cpu().squeeze().numpy() * 255).astype(np.uint8)
|
|
combined_alpha = np.minimum(alpha_mask, original_alpha)
|
|
|
|
img = Image.fromarray(img_array, mode="RGB")
|
|
img.putalpha(Image.fromarray(combined_alpha, mode="L"))
|
|
elif img_array.shape[-1] == 1:
|
|
img = Image.fromarray(img_array.squeeze(-1), mode="L")
|
|
else:
|
|
img = Image.fromarray(img_array, mode="RGB")
|
|
|
|
return pil_to_data_url(img)
|
|
except Exception as error:
|
|
log.error(f"Error in convert_tensor_to_base64: {error}")
|
|
log.debug(f"Tensor shape: {tensor.shape}, dtype: {tensor.dtype}")
|
|
raise
|
|
|
|
|
|
__all__ = ["convert_base64_to_tensor", "convert_tensor_to_base64"]
|