mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-01-27 23:00:20 +08:00
Add support for sending output image to loaded image.
Simplify workflow of img2img with new feature. * ADDED: 'recv img' button to LoadImage, LoadImageMask * ADDED: 'send to img' button to SaveImage
This commit is contained in:
parent
e85fcb822b
commit
1da4ea5898
9
nodes.py
9
nodes.py
@ -724,7 +724,9 @@ class SaveImage:
|
|||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required":
|
return {"required":
|
||||||
{"images": ("IMAGE", ),
|
{"images": ("IMAGE", ),
|
||||||
"filename_prefix": ("STRING", {"default": "ComfyUI"})},
|
"filename_prefix": ("STRING", {"default": "ComfyUI"}),
|
||||||
|
"send to img": ("IMAGESEND", )
|
||||||
|
},
|
||||||
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
|
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,7 +808,9 @@ class LoadImage:
|
|||||||
if not os.path.exists(s.input_dir):
|
if not os.path.exists(s.input_dir):
|
||||||
os.makedirs(s.input_dir)
|
os.makedirs(s.input_dir)
|
||||||
return {"required":
|
return {"required":
|
||||||
{"image": (sorted(os.listdir(s.input_dir)), )},
|
{"image": (sorted(os.listdir(s.input_dir)), ),
|
||||||
|
"recv img": (["disable", "enable"], )
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
CATEGORY = "image"
|
CATEGORY = "image"
|
||||||
@ -840,6 +844,7 @@ class LoadImageMask:
|
|||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required":
|
return {"required":
|
||||||
{"image": (sorted(os.listdir(s.input_dir)), ),
|
{"image": (sorted(os.listdir(s.input_dir)), ),
|
||||||
|
"recv img": (["disable", "enable"], ),
|
||||||
"channel": (["alpha", "red", "green", "blue"], ),}
|
"channel": (["alpha", "red", "green", "blue"], ),}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
13
server.py
13
server.py
@ -7,6 +7,8 @@ import execution
|
|||||||
import uuid
|
import uuid
|
||||||
import json
|
import json
|
||||||
import glob
|
import glob
|
||||||
|
from shutil import copyfile
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
@ -84,6 +86,17 @@ class PromptServer():
|
|||||||
files = glob.glob(os.path.join(self.web_root, 'extensions/**/*.js'), recursive=True)
|
files = glob.glob(os.path.join(self.web_root, 'extensions/**/*.js'), recursive=True)
|
||||||
return web.json_response(list(map(lambda f: "/" + os.path.relpath(f, self.web_root).replace("\\", "/"), files)))
|
return web.json_response(list(map(lambda f: "/" + os.path.relpath(f, self.web_root).replace("\\", "/"), files)))
|
||||||
|
|
||||||
|
@routes.get("/image/output_to_input/{name}")
|
||||||
|
async def copy_output_to_input_image(request):
|
||||||
|
name = request.match_info["name"]
|
||||||
|
|
||||||
|
src_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "output", name)
|
||||||
|
dest_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "input", name)
|
||||||
|
|
||||||
|
copyfile(src_dir,dest_dir)
|
||||||
|
|
||||||
|
return web.Response(status=200)
|
||||||
|
|
||||||
@routes.post("/upload/image")
|
@routes.post("/upload/image")
|
||||||
async def upload_image(request):
|
async def upload_image(request):
|
||||||
upload_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "input")
|
upload_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "input")
|
||||||
|
|||||||
@ -124,6 +124,11 @@ class ComfyApi extends EventTarget {
|
|||||||
return await resp.json();
|
return await resp.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async sendOutputToInputImage(name) {
|
||||||
|
await fetch(`/image/output_to_input/${name}`, { cache: "no-store" });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {number} number The index at which to queue the prompt, passing -1 will insert the prompt at the front of the queue
|
* @param {number} number The index at which to queue the prompt, passing -1 will insert the prompt at the front of the queue
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
import { api } from "./api.js";
|
||||||
|
import { app } from "../../scripts/app.js";
|
||||||
|
|
||||||
function getNumberDefaults(inputData, defaultStep) {
|
function getNumberDefaults(inputData, defaultStep) {
|
||||||
let defaultVal = inputData[1]["default"];
|
let defaultVal = inputData[1]["default"];
|
||||||
let { min, max, step } = inputData[1];
|
let { min, max, step } = inputData[1];
|
||||||
@ -126,6 +129,47 @@ export const ComfyWidgets = {
|
|||||||
return { widget: node.addWidget("text", inputName, defaultVal, () => {}, {}) };
|
return { widget: node.addWidget("text", inputName, defaultVal, () => {}, {}) };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
IMAGESEND(node, inputName) {
|
||||||
|
function showImage(node,uploadWidget,name) {
|
||||||
|
// Position the image somewhere sensible
|
||||||
|
if (!node.imageOffset) {
|
||||||
|
node.imageOffset = uploadWidget.last_y ? uploadWidget.last_y + 25 : 75;
|
||||||
|
}
|
||||||
|
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
node.imgs = [img];
|
||||||
|
app.graph.setDirtyCanvas(true);
|
||||||
|
};
|
||||||
|
img.src = `/view?filename=${name}&type=input`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function callback() {
|
||||||
|
const imageWidget = node.widgets.find((w) => w.name === "image");
|
||||||
|
|
||||||
|
const copied = false;
|
||||||
|
|
||||||
|
for(let i in app.graph._nodes) {
|
||||||
|
var n = app.graph._nodes[i];
|
||||||
|
if(n.type == "LoadImage" || n.type == "LoadImageMask") {
|
||||||
|
const recvWidget = n.widgets.find((w) => w.name === "recv img");
|
||||||
|
|
||||||
|
if(recvWidget.value == "enable") {
|
||||||
|
// copy current node image to 'recv img' enabled node
|
||||||
|
|
||||||
|
if(!copied) {
|
||||||
|
api.sendOutputToInputImage(imageWidget.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const thatImageWidget = n.widgets.find((w) => w.value === "image");
|
||||||
|
await showImage(n,thatImageWidget,imageWidget.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { widget: node.addWidget("button", inputName, "", () => { callback(); }, {}) };
|
||||||
|
},
|
||||||
IMAGEUPLOAD(node, inputName, inputData, app) {
|
IMAGEUPLOAD(node, inputName, inputData, app) {
|
||||||
const imageWidget = node.widgets.find((w) => w.name === "image");
|
const imageWidget = node.widgets.find((w) => w.name === "image");
|
||||||
let uploadWidget;
|
let uploadWidget;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user