Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
ComfyUI
Commits
4a326a25
"...git@developer.sourcefind.cn:chenpangpang/ComfyUI.git" did not exist on "0d972b85e616979c5832a15341972ba861197b4e"
Commit
4a326a25
authored
Mar 08, 2023
by
pythongosssss
Browse files
Added UploadImage+Mask nodes
parent
c70f0ac6
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
132 additions
and
5 deletions
+132
-5
.gitignore
.gitignore
+1
-0
nodes.py
nodes.py
+11
-1
server.py
server.py
+29
-3
web/extensions/core/uploadImage.js
web/extensions/core/uploadImage.js
+10
-0
web/scripts/app.js
web/scripts/app.js
+1
-1
web/scripts/widgets.js
web/scripts/widgets.js
+80
-0
No files found.
.gitignore
View file @
4a326a25
...
...
@@ -5,3 +5,4 @@ models/checkpoints
models/vae
models/embeddings
models/loras
uploads/
\ No newline at end of file
nodes.py
View file @
4a326a25
...
...
@@ -807,6 +807,8 @@ class LoadImage:
input_dir
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
)),
"input"
)
@
classmethod
def
INPUT_TYPES
(
s
):
if
not
os
.
path
.
exists
(
s
.
input_dir
):
os
.
makedirs
(
s
.
input_dir
)
return
{
"required"
:
{
"image"
:
(
sorted
(
os
.
listdir
(
s
.
input_dir
)),
)},
}
...
...
@@ -830,7 +832,10 @@ class LoadImage:
with
open
(
image_path
,
'rb'
)
as
f
:
m
.
update
(
f
.
read
())
return
m
.
digest
().
hex
()
class
UploadImage
(
LoadImage
):
input_dir
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
)),
"uploads"
)
class
LoadImageMask
:
input_dir
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
)),
"input"
)
@
classmethod
...
...
@@ -865,6 +870,9 @@ class LoadImageMask:
with
open
(
image_path
,
'rb'
)
as
f
:
m
.
update
(
f
.
read
())
return
m
.
digest
().
hex
()
class
UploadImageMask
(
LoadImageMask
):
input_dir
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
)),
"uploads"
)
class
ImageScale
:
upscale_methods
=
[
"nearest-exact"
,
"bilinear"
,
"area"
]
...
...
@@ -917,7 +925,9 @@ NODE_CLASS_MAPPINGS = {
"LatentUpscale"
:
LatentUpscale
,
"SaveImage"
:
SaveImage
,
"LoadImage"
:
LoadImage
,
"UploadImage"
:
UploadImage
,
"LoadImageMask"
:
LoadImageMask
,
"UploadImageMask"
:
UploadImageMask
,
"ImageScale"
:
ImageScale
,
"ImageInvert"
:
ImageInvert
,
"ConditioningCombine"
:
ConditioningCombine
,
...
...
server.py
View file @
4a326a25
...
...
@@ -6,7 +6,6 @@ import execution
import
uuid
import
json
import
glob
try
:
import
aiohttp
from
aiohttp
import
web
...
...
@@ -27,7 +26,7 @@ class PromptServer():
self
.
loop
=
loop
self
.
messages
=
asyncio
.
Queue
()
self
.
number
=
0
self
.
app
=
web
.
Application
()
self
.
app
=
web
.
Application
(
client_max_size
=
20971520
)
self
.
sockets
=
dict
()
self
.
web_root
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
)),
"web"
)
...
...
@@ -71,10 +70,37 @@ class PromptServer():
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
)))
@
routes
.
post
(
"/upload/image"
)
async
def
upload_image
(
request
):
upload_dir
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
)),
"uploads"
)
if
not
os
.
path
.
exists
(
upload_dir
):
os
.
makedirs
(
upload_dir
)
post
=
await
request
.
post
()
image
=
post
.
get
(
"image"
)
if
image
and
image
.
file
:
filename
=
image
.
filename
if
not
filename
:
return
web
.
Response
(
status
=
400
)
with
open
(
os
.
path
.
join
(
upload_dir
,
filename
),
"wb"
)
as
f
:
f
.
write
(
image
.
file
.
read
())
return
web
.
json_response
({
"name"
:
filename
})
else
:
return
web
.
Response
(
status
=
400
)
@
routes
.
get
(
"/view/{file}"
)
async
def
view_image
(
request
):
if
"file"
in
request
.
match_info
:
output_dir
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
)),
"output"
)
type
=
request
.
rel_url
.
query
.
get
(
"type"
,
"output"
)
if
type
!=
"output"
and
type
!=
"uploads"
:
return
web
.
Response
(
status
=
400
)
output_dir
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
)),
type
)
file
=
request
.
match_info
[
"file"
]
file
=
os
.
path
.
splitext
(
os
.
path
.
basename
(
file
))[
0
]
+
".png"
file
=
os
.
path
.
join
(
output_dir
,
file
)
...
...
web/extensions/core/uploadImage.js
0 → 100644
View file @
4a326a25
import
{
app
}
from
"
/scripts/app.js
"
;
app
.
registerExtension
({
name
:
"
Comfy.UploadImage
"
,
async
beforeRegisterNodeDef
(
nodeType
,
nodeData
,
app
)
{
if
(
nodeData
.
name
===
"
UploadImage
"
||
nodeData
.
name
===
"
UploadImageMask
"
)
{
nodeData
.
input
.
required
.
upload
=
[
"
IMAGEUPLOAD
"
];
}
},
});
web/scripts/app.js
View file @
4a326a25
...
...
@@ -142,7 +142,7 @@ class ComfyApp {
if
(
numImages
===
1
&&
!
imageIndex
)
{
this
.
imageIndex
=
imageIndex
=
0
;
}
let
shiftY
=
this
.
type
===
"
SaveImage
"
?
55
:
0
;
let
shiftY
=
this
.
type
===
"
SaveImage
"
?
55
:
this
.
imageOffset
||
0
;
let
dw
=
this
.
size
[
0
];
let
dh
=
this
.
size
[
1
];
dh
-=
shiftY
;
...
...
web/scripts/widgets.js
View file @
4a326a25
...
...
@@ -126,4 +126,84 @@ export const ComfyWidgets = {
return
{
widget
:
node
.
addWidget
(
"
text
"
,
inputName
,
defaultVal
,
()
=>
{},
{})
};
}
},
IMAGEUPLOAD
(
node
,
inputName
,
inputData
,
app
)
{
const
imageWidget
=
node
.
widgets
.
find
((
w
)
=>
w
.
name
===
"
image
"
);
let
uploadWidget
;
function
showImage
(
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/
${
name
}
?type=uploads`
;
}
// Add our own callback to the combo widget to render an image when it changes
const
cb
=
node
.
callback
;
imageWidget
.
callback
=
function
()
{
showImage
(
imageWidget
.
value
);
if
(
cb
)
{
return
cb
.
apply
(
this
,
arguments
);
}
};
// On load if we have a value then render the image
// The value isnt set immediately so we need to wait a moment
// No change callbacks seem to be fired on initial setting of the value
requestAnimationFrame
(()
=>
{
if
(
imageWidget
.
value
)
{
showImage
(
imageWidget
.
value
);
}
});
const
fileInput
=
document
.
createElement
(
"
input
"
);
Object
.
assign
(
fileInput
,
{
type
:
"
file
"
,
accept
:
"
image/jpeg,image/png
"
,
style
:
"
display: none
"
,
onchange
:
async
()
=>
{
if
(
fileInput
.
files
.
length
)
{
try
{
// Wrap file in formdata so it includes filename
const
body
=
new
FormData
();
body
.
append
(
"
image
"
,
fileInput
.
files
[
0
]);
const
resp
=
await
fetch
(
"
/upload/image
"
,
{
method
:
"
POST
"
,
body
,
});
if
(
resp
.
status
===
200
)
{
const
data
=
await
resp
.
json
();
showImage
(
data
.
name
);
// Add the file as an option and update the widget value
if
(
!
imageWidget
.
options
.
values
.
includes
(
data
.
name
))
{
imageWidget
.
options
.
values
.
push
(
data
.
name
);
}
imageWidget
.
value
=
data
.
name
;
}
else
{
alert
(
resp
.
status
+
"
-
"
+
resp
.
statusText
);
}
}
catch
(
error
)
{
alert
(
error
);
}
}
},
});
document
.
body
.
append
(
fileInput
);
// Create the button widget for selecting the files
uploadWidget
=
node
.
addWidget
(
"
button
"
,
"
choose file to upload
"
,
"
image
"
,
()
=>
{
fileInput
.
click
();
});
uploadWidget
.
serialize
=
false
;
return
{
widget
:
uploadWidget
};
},
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment