Compare commits

...
8 Commits
Author SHA1 Message Date
melMass 625b818d8c fix: 🐛 fix from merge 2023-08-13 01:11:28 +02:00
melMass cbbc2d0705 Merge branch 'main' into dev/psd-nodes 2023-08-13 01:04:11 +02:00
melMass 6d74670556 chore: 🔥 remove stale
This is what started all my frontend experiments, but it has been
"cleaned" since in `main`
2023-07-25 14:38:07 +02:00
melMass 61cbf4c624 feat: ✨ add alpha (mask) support 2023-07-25 14:34:55 +02:00
melMass cd39fea580 Merge branch 'main' into dev/psd-nodes 2023-07-25 02:35:53 +02:00
melMass f77ddbd6a3 fix: ✨ define dynamic input on def load 2023-07-10 20:00:47 +02:00
melMass 22b9b94679 chore: 🚧 need to push the whole file to checkout now that it's tracked 2023-07-09 23:12:25 +02:00
melMass 64b2c72cf4 feat: ✨ half working POC
Supports group but create trimming mask for each group for some reason.
I also want a better logic to group batches.
2023-07-09 23:09:15 +02:00
4 changed files with 149 additions and 1 deletions
+89
View File
@@ -0,0 +1,89 @@
from pytoshop.user import nested_layers
# from pytoshop.image_data import ImageData
from .. import utils
from ..log import log
from uuid import uuid4
from pathlib import Path
import folder_paths
from importlib import reload
class PsdSave:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"input_1": ("PSDLAYER",),
},
}
RETURN_TYPES = ()
FUNCTION = "psd_save"
CATEGORY = "psd"
OUTPUT_NODE = True
def psd_save(self, **kwargs):
groups = {
"main": [],
}
out_layers = []
for input, item in kwargs.items():
for group, layer in item.items():
if group not in groups:
groups[group] = []
groups[group].append(layer)
for group, layers in groups.items():
current_group = nested_layers.Group(
group, visible=True, opacity=255, layers=layers, closed=False
)
out_layers.append(current_group)
out_layers = nested_layers.nested_layers_to_psd(out_layers, color_mode=3)
output_name = f"{uuid4()}.psd"
output_path = Path(folder_paths.output_directory) / output_name
log.info(f"Saving PSD to {output_name}")
with open(output_path, "wb") as f:
out_layers.write(f)
return ()
class PsdLayer:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"layer_name": ("STRING", {"default": "layer"}),
"image": ("IMAGE",),
},
"optional": {"mask": ("MASK",)},
}
RETURN_TYPES = ("PSDLAYER",)
FUNCTION = "psd_layer"
CATEGORY = "psd"
def psd_layer(self, layer_name, image, mask=None):
reload(utils)
group = "main"
if "/" in layer_name:
sepname = layer_name.split("/")
# layer_name = sepname.pop() # todo: support nesting?
group = sepname[0]
layer_name = sepname[1]
psd = utils.tensor2pytolayer(image, layer_name, mask=mask)
# log.warning("Mask is currently ignored for PSD Layers...")
return ({group: psd},)
__nodes__ = [PsdLayer, PsdSave]
+1
View File
@@ -5,3 +5,4 @@ tensorflow
facexlib==0.3.0 facexlib==0.3.0
insightface==0.7.3 insightface==0.7.3
basicsr==1.4.2 basicsr==1.4.2
pytoshop
+2 -1
View File
@@ -15,4 +15,5 @@ tensorflow==2.10.1;
tb-nightly==2.12.0a20230126; platform_system == "Windows" tb-nightly==2.12.0a20230126; platform_system == "Windows"
facexlib==0.3.0 facexlib==0.3.0
# the old tf version on windows comes with a breaking protobuf version # the old tf version on windows comes with a breaking protobuf version
protobuf==3.19.6 protobuf==3.19.6
pytoshop
+57
View File
@@ -3,6 +3,13 @@ import numpy as np
import torch import torch
from pathlib import Path from pathlib import Path
import sys import sys
from typing import List, Optional
from pytoshop.user import nested_layers
from pytoshop import enums
# from pytoshop.layers import LayerMask, LayerRecord
from .log import log
from typing import List from typing import List
import signal import signal
from contextlib import suppress from contextlib import suppress
@@ -467,3 +474,53 @@ def apply_easing(value, easing_type):
# endregion # endregion
def tensor2pytolayer(
tensor: torch.Tensor,
name: str,
visible: bool = True,
opacity: int = 255,
group_id: int = 0,
blend_mode=enums.BlendMode.normal,
x: int = 0,
y: int = 0,
# channels: int = 3,
metadata: dict = {},
layer_color=0,
color_mode=None,
mask: Optional[
torch.Tensor
] = None, # Add the mask parameter with default value as None
) -> nested_layers.Image:
batch_count = tensor.size(0) if len(tensor.shape) > 3 else 1
if batch_count > 1:
raise ValueError(
f"Only one image is supported (batch size is currently {batch_count})"
)
out_channels = tensor2pil(tensor)[0]
arr = np.array(out_channels)
# If a mask is provided, convert it to numpy array
if mask is not None:
mask_arr = np.array(tensor2pil(mask)[0])
else:
mask_arr = np.full_like(arr, 255, dtype=np.uint8)
channels = [arr[:, :, 0], arr[:, :, 1], arr[:, :, 2], mask_arr[:, :, 0]]
image = nested_layers.Image(
name=name,
visible=visible,
opacity=opacity,
group_id=group_id,
blend_mode=blend_mode,
top=y,
left=x,
channels=channels,
metadata=metadata,
layer_color=layer_color,
color_mode=color_mode,
)
return image