diff --git a/PainterNode/css/painter_node_styles.css b/PainterNode/css/painter_node_styles.css index c43c619..e663f25 100644 --- a/PainterNode/css/painter_node_styles.css +++ b/PainterNode/css/painter_node_styles.css @@ -15,6 +15,7 @@ .canvas-container-painter canvas { width: 100% !important; height: auto !important; + border: 1px solid #000000; } .panelPaintBoxLeft { diff --git a/PoseNode/css/pose_node_styles.css b/PoseNode/css/pose_node_styles.css index e344ecd..2f15fdb 100644 --- a/PoseNode/css/pose_node_styles.css +++ b/PoseNode/css/pose_node_styles.css @@ -5,6 +5,7 @@ .canvas_container_openpose canvas { width: 100% !important; height: auto !important; + border: 1px solid #000000; } .pose_panelButtons { position: absolute; @@ -13,6 +14,7 @@ gap: 4px; flex-direction: column; width: fit-content; + align-items: center; } .pose_panelButtons button { width: 32px; @@ -23,14 +25,16 @@ } .pose_context_menu { position: absolute; + flex-direction: column; min-width: 100px; padding: 5px; background-color: var(--bg-color); display: flex; justify-content: center; - align-items: center; + align-items: stretch; border: 1px solid var(--border-color); gap: 2px; + font-size: 0.4rem; } .pose_btn_context { border: 1px solid; @@ -44,3 +48,27 @@ color: var(--error-text); border-color: var(--error-text); } + +.pose_SetBackgroundBg { + position: relative; + width: 24px; + height: 27px; + padding: 0; + outline: 0; + border: 0; + margin: 0; + background: none; +} + +.pose_SetBackgroundBg:before { + content: "BG"; + position: absolute; + font-size: 0.4rem; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); +} + +.pose_SetBackgroundBg.lightColor:before { + color: #000000; +} diff --git a/PoseNode/js/pose_node.js b/PoseNode/js/pose_node.js index 832b4b2..cc1b7b5 100644 --- a/PoseNode/js/pose_node.js +++ b/PoseNode/js/pose_node.js @@ -115,6 +115,7 @@ class OpenPose { redo_history: [], currentCanvasSize: { width: 512, height: 512 }, background: null, + backgroundColor: null, }; this.canvas = this.initCanvas(canvasElement); @@ -157,7 +158,7 @@ class OpenPose { if (tmpImage) this.setBackground(tmpImage); - this.canvas.backgroundColor = "#000"; + this.canvas.backgroundColor = "#000000"; this.canvas.renderAll(); const res = []; @@ -261,7 +262,7 @@ class OpenPose { initCanvas() { this.canvas = new fabric.Canvas(this.canvas, { - backgroundColor: "#000", + backgroundColor: "#000000", preserveObjectStacking: true, containerClass: "canvas_container_openpose", width: this.settings.currentCanvasSize.width, @@ -377,7 +378,7 @@ class OpenPose { return; } - this.settings.redo_history.length = 0; + this.updateHistoryUndoRedo(); this.uploadPoseFile(this.node.name); }); @@ -388,30 +389,41 @@ class OpenPose { return this.canvas; } - undo() { - if (this.settings.undo_history.length > 0) { - if (this.settings.undo_history.length > 1) - this.settings.redo_history.push(this.settings.undo_history.pop()); + updateHistoryUndoRedo() { + this.settings.undo_history.push(this.getJSON()); + this.settings.redo_history = []; + } - const content = + undo() { + console.log("UNDO"); + if (this.settings.undo_history.length > 1) { + const last = this.settings.undo_history.pop(); + this.settings.redo_history.push(last); + + const previous = this.settings.undo_history[this.settings.undo_history.length - 1]; + this.loadPreset(previous); + this.canvas.renderAll(); + this.uploadPoseFile(this.node.name); + } + } + + redo() { + console.log("RENDO"); + if (this.settings.redo_history.length > 0) { + const content = this.settings.redo_history.pop(); + this.settings.undo_history.push(content); + this.loadPreset(content); + this.canvas.renderAll(); this.uploadPoseFile(this.node.name); } } - redo() { - if (this.settings.redo_history.length > 0) { - const content = this.settings.redo_history.pop(); - this.settings.undo_history.push(content); - this.loadPreset(content); - - this.canvas.renderAll(); - - this.uploadPoseFile(this.node.name); - } + saveData() { + app?.extensionManager?.workflow?.activeWorkflow?.changeTracker?.checkState(); } async resetCanvas(reset_size = false) { @@ -426,7 +438,7 @@ class OpenPose { const backgroundImg = this.canvas.backgroundImage; this.canvas.clear(); - this.canvas.backgroundColor = "#000"; + this.canvas.backgroundColor = "#000000"; this.addPose(); this.setBackground(backgroundImg); @@ -488,8 +500,6 @@ class OpenPose { this.canvas.backgroundImage = null; this.canvas.renderAll(); - this.settings.undo_history.push(this.getJSON()); - this.canvas.lowerCanvasEl.toBlob((blob) => { const formData = new FormData(); formData.append("image", blob, fileName); @@ -646,7 +656,8 @@ function createOpenPose(node, inputName, inputData, app) { let panelButtons = $el("div.pose_panelButtons.comfy-menu-btns", [ $el("button", { textContent: "Ref", - title: "Reference Image (Right click remove)", + title: + "Reference Image (Right click remove and set transparent background)", onclick: () => { node.openPose.backgroundInput.value = ""; node.openPose.backgroundInput.click(); @@ -671,6 +682,15 @@ function createOpenPose(node, inputName, inputData, app) { node.openPose.canvas.backgroundImage = null; node.openPose.canvas.renderAll(); } + + if (target.classList.contains("transparentBG")) { + node.openPose.canvas.backgroundColor = "transparent"; + node.openPose.settings.backgroundColor = "transparent"; + node.openPose.canvas.renderAll(); + } + + node.openPose.saveData(); + node.openPose.uploadPoseFile(node.name); }, onmouseleave: () => menu && menu.remove(), }, @@ -678,6 +698,9 @@ function createOpenPose(node, inputName, inputData, app) { $el("div.pose_btn_context.remBG", { textContent: "Remove background", }), + $el("div.pose_btn_context.transparentBG", { + textContent: "Set transparent background", + }), ] ); @@ -685,15 +708,31 @@ function createOpenPose(node, inputName, inputData, app) { app.graph.setDirtyCanvas(true, false); }, }), + $el("input.pose_SetBackgroundBg", { + type: "color", + title: "Set background color", + value: this.settings?.backgroundColor ?? "#000000", + oninput: (e) => { + node.openPose.canvas.backgroundColor = e.target.value; + node.openPose.settings.backgroundColor = e.target.value; + e.target.classList.toggle("lightColor", e.target.value === "#ffffff"); + node.openPose.canvas.renderAll(); + node.openPose.saveData(); + }, + }), $el("button", { textContent: "⟲", title: "Undo", - onclick: () => node.openPose.undo(), + onclick: () => { + node.openPose.undo(); + }, }), $el("button", { textContent: "⟳", title: "Redo", - onclick: () => node.openPose.redo(), + onclick: () => { + node.openPose.redo(); + }, }), $el("button.clear_history", { textContent: "✖", @@ -709,7 +748,6 @@ function createOpenPose(node, inputName, inputData, app) { node.openPose.setPose(default_keypoints); node.openPose.undo_history.push(node.openPose.getJSON()); node.openPose.history_change = true; - node.openPose.updateHistoryData(); } }, }), @@ -876,6 +914,7 @@ app.registerExtension({ const { currentCanvasSize, background, + backgroundColor, undo_history, redo_history, } = data; @@ -890,6 +929,13 @@ app.registerExtension({ : { keypoints: default_keypoints } ); + if (backgroundColor) { + this.openPose.canvas.backgroundColor = backgroundColor; + this.openPoseWrapper.querySelector( + ".pose_SetBackgroundBg" + ).value = backgroundColor; + } + if (background) { fabric.Image.fromURL(background, (img) => { img.set({ diff --git a/PoseNode/pose_node.py b/PoseNode/pose_node.py index a5d8744..8de1f24 100644 --- a/PoseNode/pose_node.py +++ b/PoseNode/pose_node.py @@ -34,7 +34,7 @@ class PoseNode(object): i = Image.open(image_path) i = ImageOps.exif_transpose(i) - image = i.convert("RGB") + image = i.convert("RGBA") image = np.array(image).astype(np.float32) / 255.0 image = torch.from_numpy(image)[None,] diff --git a/pyproject.toml b/pyproject.toml index 32827ce..e9c112a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui_custom_nodes_alekpet" description = "Nodes: PoseNode, PainterNode, TranslateTextNode, TranslateCLIPTextEncodeNode, DeepTranslatorTextNode, DeepTranslatorCLIPTextEncodeNode, ArgosTranslateTextNode, ArgosTranslateCLIPTextEncodeNode, ChatGLM4TranslateCLIPTextEncodeNode, ChatGLM4TranslateTextNode, ChatGLM4InstructNode, ChatGLM4InstructMediaNode, PreviewTextNode, HexToHueNode, ColorsCorrectNode, IDENode." -version = "1.0.76" +version = "1.0.77" license = { file = "LICENSE" } [project.urls]