diff --git a/README.md b/README.md index 90931141d..877f46433 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ComfyUI ======= -A powerful and modular stable diffusion GUI. +A powerful and modular stable diffusion GUI and backend. ----------- ![ComfyUI Screenshot](comfyui_screenshot.png) @@ -146,9 +146,9 @@ This will let you use: pip3.10 to install all the dependencies. ## How to increase generation speed? -Make sure you use the CheckpointLoaderSimple node to load checkpoints. It will auto pick the right settings depending on your GPU. +Make sure you use the regular loaders/Load Checkpoint node to load checkpoints. It will auto pick the right settings depending on your GPU. -You can set this command line setting to disable the upcasting to fp32 in some cross attention operations which will increase your speed. Note that this doesn't do anything when xformers is enabled and will very likely give you black images on SD2.x models. +You can set this command line setting to disable the upcasting to fp32 in some cross attention operations which will increase your speed. Note that this will very likely give you black images on SD2.x models. If you use xformers this option does not do anything. ```--dont-upcast-attention``` diff --git a/comfyui_screenshot.png b/comfyui_screenshot.png index c357e2439..73272eae6 100644 Binary files a/comfyui_screenshot.png and b/comfyui_screenshot.png differ diff --git a/nodes.py b/nodes.py index 14a73bcd7..946c66857 100644 --- a/nodes.py +++ b/nodes.py @@ -940,6 +940,8 @@ class LoadImageMask: input_dir = folder_paths.get_input_directory() image_path = os.path.join(input_dir, image) i = Image.open(image_path) + if i.getbands() != ("R", "G", "B", "A"): + i = i.convert("RGBA") mask = None c = channel[0].upper() if c in i.getbands(): diff --git a/notebooks/comfyui_colab.ipynb b/notebooks/comfyui_colab.ipynb index d17f9877d..071a89969 100644 --- a/notebooks/comfyui_colab.ipynb +++ b/notebooks/comfyui_colab.ipynb @@ -86,6 +86,11 @@ "#!wget -c https://huggingface.co/waifu-diffusion/wd-1-5-beta2/resolve/main/checkpoints/wd-1-5-beta2-fp16.safetensors -P ./models/checkpoints/\n", "\n", "\n", + "# unCLIP models\n", + "#!wget -c https://huggingface.co/comfyanonymous/illuminatiDiffusionV1_v11_unCLIP/resolve/main/illuminatiDiffusionV1_v11-unclip-h-fp16.safetensors -P ./models/checkpoints/\n", + "#!wget -c https://huggingface.co/comfyanonymous/wd-1.5-beta2_unCLIP/resolve/main/wd-1-5-beta2-aesthetic-unclip-h-fp16.safetensors -P ./models/checkpoints/\n", + "\n", + "\n", "# VAE\n", "!wget -c https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.safetensors -P ./models/vae/\n", "#!wget -c https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt -P ./models/vae/\n", diff --git a/web/extensions/core/colorPalette.js b/web/extensions/core/colorPalette.js index a08d46684..94bea9ab3 100644 --- a/web/extensions/core/colorPalette.js +++ b/web/extensions/core/colorPalette.js @@ -5,9 +5,9 @@ import { api } from "/scripts/api.js"; // Manage color palettes const colorPalettes = { - "palette_1": { - "id": "palette_1", - "name": "Palette 1", + "dark": { + "id": "dark", + "name": "Dark (Default)", "colors": { "node_slot": { "CLIP": "#FFD500", // bright yellow @@ -45,6 +45,70 @@ const colorPalettes = { "EVENT_LINK_COLOR": "#A86", "CONNECTING_LINK_COLOR": "#AFA", }, + "comfy_base": { + "fg-color": "#fff", + "bg-color": "#202020", + "comfy-menu-bg": "#353535", + "comfy-input-bg": "#222", + "input-text": "#ddd", + "descrip-text": "#999", + "drag-text": "#ccc", + "error-text": "#ff4444", + "border-color": "#4e4e4e" + } + }, + }, + "light": { + "id": "light", + "name": "Light", + "colors": { + "node_slot": { + "CLIP": "#FFA726", // orange + "CLIP_VISION": "#5C6BC0", // indigo + "CLIP_VISION_OUTPUT": "#8D6E63", // brown + "CONDITIONING": "#EF5350", // red + "CONTROL_NET": "#66BB6A", // green + "IMAGE": "#42A5F5", // blue + "LATENT": "#AB47BC", // purple + "MASK": "#9CCC65", // light green + "MODEL": "#7E57C2", // deep purple + "STYLE_MODEL": "#D4E157", // lime + "VAE": "#FF7043", // deep orange + }, + "litegraph_base": { + "NODE_TITLE_COLOR": "#222", + "NODE_SELECTED_TITLE_COLOR": "#000", + "NODE_TEXT_SIZE": 14, + "NODE_TEXT_COLOR": "#444", + "NODE_SUBTEXT_SIZE": 12, + "NODE_DEFAULT_COLOR": "#F7F7F7", + "NODE_DEFAULT_BGCOLOR": "#F5F5F5", + "NODE_DEFAULT_BOXCOLOR": "#CCC", + "NODE_DEFAULT_SHAPE": "box", + "NODE_BOX_OUTLINE_COLOR": "#000", + "DEFAULT_SHADOW_COLOR": "rgba(0,0,0,0.1)", + "DEFAULT_GROUP_FONT": 24, + + "WIDGET_BGCOLOR": "#D4D4D4", + "WIDGET_OUTLINE_COLOR": "#999", + "WIDGET_TEXT_COLOR": "#222", + "WIDGET_SECONDARY_TEXT_COLOR": "#555", + + "LINK_COLOR": "#4CAF50", + "EVENT_LINK_COLOR": "#FF9800", + "CONNECTING_LINK_COLOR": "#2196F3", + }, + "comfy_base": { + "fg-color": "#222", + "bg-color": "#DDD", + "comfy-menu-bg": "#F5F5F5", + "comfy-input-bg": "#C9C9C9", + "input-text": "#222", + "descrip-text": "#444", + "drag-text": "#555", + "error-text": "#F44336", + "border-color": "#CCC" + } }, }, "solarized": { @@ -52,49 +116,60 @@ const colorPalettes = { "name": "Solarized", "colors": { "node_slot": { - "CLIP": "#859900", // Green - "CLIP_VISION": "#6c71c4", // Indigo - "CLIP_VISION_OUTPUT": "#859900", // Green - "CONDITIONING": "#d33682", // Magenta - "CONTROL_NET": "#cb4b16", // Orange - "IMAGE": "#dc322f", // Red - "LATENT": "#268bd2", // Blue - "MASK": "#073642", // Base02 - "MODEL": "#cb4b16", // Orange - "STYLE_MODEL": "#073642", // Base02 - "UPSCALE_MODEL": "#6c71c4", // Indigo - "VAE": "#586e75", // Base1 + "CLIP": "#2AB7CA", // light blue + "CLIP_VISION": "#6c71c4", // blue violet + "CLIP_VISION_OUTPUT": "#859900", // olive green + "CONDITIONING": "#d33682", // magenta + "CONTROL_NET": "#d1ffd7", // light mint green + "IMAGE": "#5940bb", // deep blue violet + "LATENT": "#268bd2", // blue + "MASK": "#CCC9E7", // light purple-gray + "MODEL": "#dc322f", // red + "STYLE_MODEL": "#1a998a", // teal + "UPSCALE_MODEL": "#054A29", // dark green + "VAE": "#facfad", // light pink-orange }, "litegraph_base": { - "NODE_TITLE_COLOR": "#fdf6e3", - "NODE_SELECTED_TITLE_COLOR": "#b58900", + "NODE_TITLE_COLOR": "#fdf6e3", // Base3 + "NODE_SELECTED_TITLE_COLOR": "#A9D400", "NODE_TEXT_SIZE": 14, - "NODE_TEXT_COLOR": "#657b83", + "NODE_TEXT_COLOR": "#657b83", // Base00 "NODE_SUBTEXT_SIZE": 12, - "NODE_DEFAULT_COLOR": "#586e75", - "NODE_DEFAULT_BGCOLOR": "#073642", - "NODE_DEFAULT_BOXCOLOR": "#839496", + "NODE_DEFAULT_COLOR": "#094656", + "NODE_DEFAULT_BGCOLOR": "#073642", // Base02 + "NODE_DEFAULT_BOXCOLOR": "#839496", // Base0 "NODE_DEFAULT_SHAPE": "box", - "NODE_BOX_OUTLINE_COLOR": "#fdf6e3", + "NODE_BOX_OUTLINE_COLOR": "#fdf6e3", // Base3 "DEFAULT_SHADOW_COLOR": "rgba(0,0,0,0.5)", "DEFAULT_GROUP_FONT": 24, - "WIDGET_BGCOLOR": "#002b36", - "WIDGET_OUTLINE_COLOR": "#839496", - "WIDGET_TEXT_COLOR": "#fdf6e3", - "WIDGET_SECONDARY_TEXT_COLOR": "#93a1a1", + "WIDGET_BGCOLOR": "#002b36", // Base03 + "WIDGET_OUTLINE_COLOR": "#839496", // Base0 + "WIDGET_TEXT_COLOR": "#fdf6e3", // Base3 + "WIDGET_SECONDARY_TEXT_COLOR": "#93a1a1", // Base1 - "LINK_COLOR": "#2aa198", - "EVENT_LINK_COLOR": "#268bd2", - "CONNECTING_LINK_COLOR": "#859900", + "LINK_COLOR": "#2aa198", // Solarized Cyan + "EVENT_LINK_COLOR": "#268bd2", // Solarized Blue + "CONNECTING_LINK_COLOR": "#859900", // Solarized Green }, + "comfy_base": { + "fg-color": "#fdf6e3", // Base3 + "bg-color": "#002b36", // Base03 + "comfy-menu-bg": "#073642", // Base02 + "comfy-input-bg": "#002b36", // Base03 + "input-text": "#93a1a1", // Base1 + "descrip-text": "#586e75", // Base01 + "drag-text": "#839496", // Base0 + "error-text": "#dc322f", // Solarized Red + "border-color": "#657b83" // Base00 + } }, } }; const id = "Comfy.ColorPalette"; const idCustomColorPalettes = "Comfy.CustomColorPalettes"; -const defaultColorPaletteId = "palette_1"; +const defaultColorPaletteId = "dark"; const els = {} // const ctxMenu = LiteGraph.ContextMenu; app.registerExtension({ @@ -236,10 +311,12 @@ app.registerExtension({ const loadColorPalette = async (colorPalette) => { colorPalette = await completeColorPalette(colorPalette); if (colorPalette.colors) { + // Sets the colors of node slots and links if (colorPalette.colors.node_slot) { Object.assign(app.canvas.default_connection_color_byType, colorPalette.colors.node_slot); Object.assign(LGraphCanvas.link_type_colors, colorPalette.colors.node_slot); } + // Sets the colors of the LiteGraph objects if (colorPalette.colors.litegraph_base) { // Everything updates correctly in the loop, except the Node Title and Link Color for some reason app.canvas.node_title_color = colorPalette.colors.litegraph_base.NODE_TITLE_COLOR; @@ -251,6 +328,13 @@ app.registerExtension({ } } } + // Sets the color of ComfyUI elements + if (colorPalette.colors.comfy_base) { + const rootStyle = document.documentElement.style; + for (const key in colorPalette.colors.comfy_base) { + rootStyle.setProperty('--' + key, colorPalette.colors.comfy_base[key]); + } + } app.canvas.draw(true, true); } }; diff --git a/web/extensions/core/saveImageExtraOutput.js b/web/extensions/core/saveImageExtraOutput.js index ce97b5491..6032d4cc7 100644 --- a/web/extensions/core/saveImageExtraOutput.js +++ b/web/extensions/core/saveImageExtraOutput.js @@ -90,7 +90,7 @@ app.registerExtension({ const r = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined; if (!this.properties || !("Node name for S&R" in this.properties)) { - this.addProperty("Node name for S&R", this.title, "string"); + this.addProperty("Node name for S&R", this.constructor.type, "string"); } return r; diff --git a/web/scripts/app.js b/web/scripts/app.js index 89a1ee01c..a5ed107b0 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -362,8 +362,20 @@ class ComfyApp { if (n && n.onDragDrop && (await n.onDragDrop(event))) { return; } - + // Dragging from Chrome->Firefox there is a file but its a bmp, so ignore that + if (event.dataTransfer.files.length && event.dataTransfer.files[0].type !== "image/bmp") { await this.handleFile(event.dataTransfer.files[0]); + } else { + // Try loading the first URI in the transfer list + const validTypes = ["text/uri-list", "text/x-moz-url"]; + const match = [...event.dataTransfer.types].find((t) => validTypes.find(v => t === v)); + if (match) { + const uri = event.dataTransfer.getData(match)?.split("\n")?.[0]; + if (uri) { + await this.handleFile(await (await fetch(uri)).blob()); + } + } + } }); // Always clear over node on drag leave @@ -1106,7 +1118,7 @@ class ComfyApp { importA1111(this.graph, pngInfo.parameters); } } - } else if (file.type === "application/json" || file.name.endsWith(".json")) { + } else if (file.type === "application/json" || file.name?.endsWith(".json")) { const reader = new FileReader(); reader.onload = () => { this.loadGraphData(JSON.parse(reader.result)); diff --git a/web/style.css b/web/style.css index d00a2fbe2..34e31726c 100644 --- a/web/style.css +++ b/web/style.css @@ -1,6 +1,13 @@ :root { --fg-color: #000; --bg-color: #fff; + --comfy-menu-bg: #353535; + --comfy-input-bg: #222; + --input-text: #ddd; + --descrip-text: #999; + --drag-text: #ccc; + --error-text: #ff4444; + --border-color: #4e4e4e; } @media (prefers-color-scheme: dark) { @@ -25,8 +32,8 @@ body { } .comfy-multiline-input { - background-color: var(--bg-color); - color: var(--fg-color); + background-color: var(--comfy-input-bg); + color: var(--input-text); overflow: hidden; overflow-y: auto; padding: 2px; @@ -39,8 +46,8 @@ body { position: fixed; /* Stay in place */ z-index: 100; /* Sit on top */ padding: 30px 30px 10px 30px; - background-color: #353535; /* Modal background */ - color: #ff4444; + background-color: var(--comfy-menu-bg); /* Modal background */ + color: var(--error-text); box-shadow: 0px 0px 20px #888888; border-radius: 10px; top: 50%; @@ -82,8 +89,8 @@ body { display: flex; flex-direction: column; align-items: center; - color: #999; - background-color: #353535; + color: var(--descrip-text); + background-color: var(--comfy-menu-bg); font-family: sans-serif; padding: 10px; border-radius: 0 8px 8px 8px; @@ -103,7 +110,7 @@ body { .comfy-menu-btns button { font-size: 10px; width: 50%; - color: #999 !important; + color: var(--descrip-text) !important; } .comfy-menu > button { @@ -114,10 +121,10 @@ body { .comfy-menu-btns button, .comfy-menu .comfy-list button, .comfy-modal button{ - color: #ddd; - background-color: #222; + color: var(--input-text); + background-color: var(--comfy-input-bg); border-radius: 8px; - border-color: #4e4e4e; + border-color: var(--border-color); border-style: solid; margin-top: 2px; } @@ -136,7 +143,7 @@ body { font-size: 12px; font-family: sans-serif; letter-spacing: 2px; - color: #cccccc; + color: var(--drag-text); text-shadow: 1px 0 1px black; position: absolute; top: 0; @@ -152,7 +159,7 @@ body { } .comfy-list { - color: #999; + color: var(--descrip-text); background-color: #333; margin-bottom: 10px; border-color: #4e4e4e; @@ -163,7 +170,7 @@ body { overflow-y: scroll; max-height: 100px; min-height: 25px; - background-color: #222; + background-color: var(--comfy-input-bg); padding: 5px; } @@ -206,16 +213,16 @@ button.comfy-queue-btn { .comfy-modal.comfy-manage-templates { text-align: center; font-family: sans-serif; - color: #999; + color: var(--descrip-text); z-index: 99; } .comfy-modal input, .comfy-modal select { - color: #ddd; - background-color: #222; + color: var(--input-text); + background-color: var(--comfy-input-bg); border-radius: 8px; - border-color: #4e4e4e; + border-color: var(--border-color); border-style: solid; font-size: inherit; } @@ -240,7 +247,7 @@ button.comfy-queue-btn { .graphdialog .name { font-size: 14px; font-family: sans-serif; - color: #999999; + color: var(--descrip-text); } .graphdialog button { @@ -251,10 +258,10 @@ button.comfy-queue-btn { } .graphdialog input, .graphdialog textarea, .graphdialog select { - background-color: #222; + background-color: var(--comfy-input-bg); border: 2px solid; - border-color: #444444; - color: #ddd; + border-color: var(--border-color); + color: var(--input-text); border-radius: 12px 0 0 12px; }