diff --git a/CHANGELOG.md b/CHANGELOG.md index a091ba6..2cb0940 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,10 @@ # Changelog -## [0.36.7] - 2025-03-20 -### Added +## [0.31.0] - 2025-03-20 +- 增加自定义ComfyUI logo功能 + +## [0.30.7] - 2025-03-20 + - 增加`image_composer`节点 - 增加`image_cropper`节点 - 增加`image_resizer`节点 @@ -11,21 +14,21 @@ ## [0.26.3] - 2025-03-12 -### Added + - 增加Load Image Folder节点 - 增加`remove bg` `mask blur plus` `mask preview plus`节点的invert mask功能 ## [0.25.1] - 2025-03-12 -### Added + - 增加节点右键菜单 Run 功能(快速对节点调试) - 增加组右键菜单 Run 功能(快速对组节点调试) ## [0.21.0] - 2025-03-02 -### Added + - 增加BiRefNet ## [0.20.0] - 2025-02-27 -### Added + - 增加AIO翻译节点 - 增加RemBG背景移除节点组 @@ -43,7 +46,7 @@ - 增加部分节点的数据显示功能 ## [0.9.0] - 2025-02-24 -### Added + - 增加腾讯AI翻译节点 Add Tencent AI translation nod e @@ -52,7 +55,7 @@ ## [0.7.0] - 2025-01-19 -### Added + - 增加abc数学 abc Math 节点,支持多种数学运算。 Added the abc Math node, supporting various mathematical operations. @@ -61,7 +64,7 @@ ## [0.3.6] - 2025-01-18 -### Added + - 增加大壮提示词 Strong Prompt 节点,支持负向提示词零化功能以及预设样式编辑与导入。 Added the Strong Prompt node, supporting negative prompt nullification and preset style editing and importing. - 增加百度AI翻译 Baidu Translater 节点,支持双文本翻译、自动检测语言及百度API配置。 @@ -79,14 +82,14 @@ --- ## [0.1.3] - 2024-10-23 -### Added + - 色彩调节节点中增加滤镜强度调节。 Added filter intensity adjustment in the Color Adjustment node. --- ## [0.1.2] - 2024-10-23 -### Added + - 增加色彩调节节点。 Added the Color Adjustment node. - 支持模拟相机曝光调节、对比度、色温、色调、饱和度调节。 @@ -99,7 +102,7 @@ --- ## [0.0.1] - 2024-10-19 -### Added + - 创建自定义保存图像节点。 Created the Custom SaveImage node. - 支持保存为 PNG 和 JPG 格式。 diff --git a/README.md b/README.md index d36568d..6e8da62 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,15 @@ This is a custom node utility package developed for ComfyUI. Initially created f **📌 所有 KayTool 节点包用到的资源都在 `ComfyUI/custom_nodes/kaytool` 文件夹内。| All KayTool node packages use resources in the `ComfyUI/custom_nodes/kaytool` folder.** + +### 自定义ComfyUI Logo功能 Custom ComfyUI Logo +- 在设置菜单中(KayTool)自定义 ComfyUI 的 Logo,支持 PNG、JPG、JPEG 格式。 + Customize the ComfyUI Logo in the settings menu (KayTool), supporting PNG, JPG, and JPEG formats. +- 将 LOGO 文件重命名为“logo.(png/jpg/jpeg/ico)”并将其放置在“/ComfyUI/custom_nodes/kaytool”文件夹。 + Rename the LOGO file to "logo.(png/jpg/jpeg/ico)" and place it in "/ComfyUI/custom_nodes/kaytool" + +--- + ### 右键快速 Run 功能 Quick Run Options via Right-Click (Run Group/Node) - 右键点击节点组或节点,选择“Run Group/Node”,即可快速运行节点组或节点进行调试。 - Right-click on a node group or node, select "Run Group/Node," and quickly run the node group or node for debugging. diff --git a/__init__.py b/__init__.py index fd2a0f8..acfbf42 100644 --- a/__init__.py +++ b/__init__.py @@ -1,4 +1,6 @@ import os +import json +from aiohttp import web from .nodes.custom_save_image import CustomSaveImage from .nodes.color_adjustment import ColorAdjustment from .nodes.strong_prompt import StrongPrompt @@ -14,15 +16,15 @@ from .nodes.slider_100 import Slider100 from .nodes.slider_10 import Slider10 from .nodes.to_int import ToInt from .nodes.remove_bg import RemoveBG -from .nodes.rembg_loader import RemBGLoader -from .nodes.birefnet_loader import BiRefNetLoader +from .nodes.rembg_loader import RemBGLoader +from .nodes.birefnet_loader import BiRefNetLoader from .nodes.preview_mask import PreviewMask -from .nodes.mask_blur_plus import MaskBlurPlus +from .nodes.mask_blur_plus import MaskBlurPlus from .nodes.preview_mask_plus import PreviewMaskPlus -from .nodes.ab_images import ABImages -from .nodes.load_image_folder import LoadImageFolder -from .nodes.image_composer import ImageComposer -from .nodes.image_cropper import ImageCropper +from .nodes.ab_images import ABImages +from .nodes.load_image_folder import LoadImageFolder +from .nodes.image_composer import ImageComposer +from .nodes.image_cropper import ImageCropper from .nodes.image_resizer import ImageResizer from .nodes.mask_filler import MaskFiller @@ -42,15 +44,15 @@ NODE_CLASS_MAPPINGS = { "Slider_10": Slider10, "To_Int": ToInt, "Remove_BG": RemoveBG, - "RemBG_Loader": RemBGLoader, - "BiRefNet_Loader": BiRefNetLoader, + "RemBG_Loader": RemBGLoader, + "BiRefNet_Loader": BiRefNetLoader, "Preview_Mask": PreviewMask, - "Mask_Blur_Plus": MaskBlurPlus, + "Mask_Blur_Plus": MaskBlurPlus, "Preview_Mask_Plus": PreviewMaskPlus, "AB_Images": ABImages, "Load_Image_Folder": LoadImageFolder, - "Image_Composer": ImageComposer, - "Image_Cropper": ImageCropper, + "Image_Composer": ImageComposer, + "Image_Cropper": ImageCropper, "Image_Resizer": ImageResizer, "Mask_Filler": MaskFiller, } @@ -71,17 +73,54 @@ NODE_DISPLAY_NAME_MAPPINGS = { "Slider_10": "𝙆 Slider 10", "To_Int": "𝙆 To Int", "Remove_BG": "𝙆 Remove BG", - "RemBG_Loader": "𝙆 RemBG Loader", - "BiRefNet_Loader": "𝙆 BiRefNet Loader", + "RemBG_Loader": "𝙆 RemBG Loader", + "BiRefNet_Loader": "𝙆 BiRefNet Loader", "Preview_Mask": "𝙆 Preview Mask", - "Mask_Blur_Plus": "𝙆 Mask Blur +", + "Mask_Blur_Plus": "𝙆 Mask Blur +", "Preview_Mask_Plus": "𝙆 Preview Mask +", "AB_Images": "𝙆 ab Images", "Load_Image_Folder": "𝙆 Load Image Folder", - "Image_Composer": "𝙆 Image Composer", - "Image_Cropper": "𝙆 Image Cropper", + "Image_Composer": "𝙆 Image Composer", + "Image_Cropper": "𝙆 Image Cropper", "Image_Resizer": "𝙆 Image Resizer", "Mask_Filler": "𝙆 Mask Filler", } -WEB_DIRECTORY = "web" \ No newline at end of file +WEB_DIRECTORY = "web" +SETTINGS_FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "settings.json") +LOGO_DIR = os.path.dirname(os.path.realpath(__file__)) +VALID_EXTENSIONS = [".png", ".jpg", ".jpeg", ".ico"] + +async def load_settings(request): + if os.path.exists(SETTINGS_FILE): + with open(SETTINGS_FILE, "r") as f: + return web.json_response(json.load(f)) + return web.json_response({"ShowRunOption": True, "ShowSetGetOptions": True, "EnableCustomLogo": True}) + +async def save_settings(request): + data = await request.json() + settings = {} + if os.path.exists(SETTINGS_FILE): + with open(SETTINGS_FILE, "r") as f: + settings = json.load(f) + settings.update(data) + with open(SETTINGS_FILE, "w") as f: + json.dump(settings, f, indent=2) + return web.Response(status=200) + +async def serve_logo(request): + for ext in VALID_EXTENSIONS: + logo_file = os.path.join(LOGO_DIR, f"logo{ext}") + if os.path.exists(logo_file): + print(f"[Kaytool] Serving logo: {logo_file}") + return web.FileResponse(logo_file) + print("[Kaytool] Logo not found") + return web.Response(status=404, text="Logo not found") + +import server +app = server.PromptServer.instance +app.app.add_routes([ + web.get("/kaytool/load_settings", load_settings), + web.post("/kaytool/save_settings", save_settings), + web.get("/kaytool/logo", serve_logo) +]) \ No newline at end of file diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..1b33d92 Binary files /dev/null and b/logo.png differ diff --git a/pyproject.toml b/pyproject.toml index ccd4f8e..79b8631 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "kaytool" -description ="KayTool boosts ComfyUI workflow efficiency with ultra-practical tools: BiRefNet/RemBG for background/mask tasks, wireless data transfer (Get & Out), AI translation (Tencent/Baidu), dynamic math operations, image processing tailored for the most popular workflows (size, color, blur, expand, merge, crop), flexible text handling, precision sliders, metadata and color profile-supported image saving, quick Run options via right-click (Run Group/Node), loading image folders to create batch processing workflows, and more." -version = "0.30.7" +description ="KayTool boosts ComfyUI workflow efficiency with ultra-practical tools: BiRefNet/RemBG for background/mask tasks, wireless data transfer (Get & Out), AI translation (Tencent/Baidu), dynamic math operations, image processing tailored for the most popular workflows (size, color, blur, expand, merge, crop), flexible text handling, precision sliders, metadata and color profile-supported image saving, quick Run options via right-click (Run Group/Node), loading image folders to create batch processing workflows,Custom ComfyUI logo and more." +version = "0.31.0" license = {file = "LICENSE"} dependencies = ["rembg, timm"] diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..45f31e2 --- /dev/null +++ b/settings.json @@ -0,0 +1,5 @@ +{ + "ShowRunOption": true, + "ShowSetGetOptions": true, + "ShowCustomLogo": true +} \ No newline at end of file diff --git a/web/settings.js b/web/settings.js index a07dc07..effa71d 100644 --- a/web/settings.js +++ b/web/settings.js @@ -3,6 +3,53 @@ import { app } from "/scripts/app.js"; app.registerExtension({ name: "Kaytool.Settings", async setup() { + async function loadSettings() { + try { + const response = await fetch("/kaytool/load_settings"); + const settings = await response.json(); + app.ui.settings.setSettingValue("Kaytool.ShowRunOption", settings.ShowRunOption ?? true); + app.ui.settings.setSettingValue("Kaytool.ShowSetGetOptions", settings.ShowSetGetOptions ?? true); + app.ui.settings.setSettingValue("Kaytool.ShowCustomLogo", settings.ShowCustomLogo ?? true); + } catch (e) { + console.error("[Kaytool] Failed to load settings:", e); + app.ui.settings.setSettingValue("Kaytool.ShowRunOption", true); + app.ui.settings.setSettingValue("Kaytool.ShowSetGetOptions", true); + app.ui.settings.setSettingValue("Kaytool.ShowCustomLogo", true); + } + } + + async function saveSettings(key, value) { + try { + await fetch("/kaytool/save_settings", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ [key]: value }) + }); + } catch (e) { + console.error("[Kaytool] Failed to save settings:", e); + } + } + + async function updateFavicon() { + const showLogo = app.ui.settings.getSettingValue("Kaytool.ShowCustomLogo", true); + let link = document.querySelector("link[rel='icon']"); + if (!link) { + link = document.createElement("link"); + link.rel = "icon"; + document.head.appendChild(link); + } + if (showLogo) { + const response = await fetch("/kaytool/logo"); + if (response.ok) { + link.href = "/kaytool/logo?" + new Date().getTime(); + } else { + link.href = "/favicon.ico"; + } + } else { + link.href = "/favicon.ico"; + } + } + app.ui.settings.addSetting({ id: "Kaytool.ShowRunOption", name: "Show Kaytool ▶️ Run Option in Right-Click Menu", @@ -10,6 +57,7 @@ app.registerExtension({ defaultValue: true, onChange: (value) => { console.log("Kaytool Run Option display set to:", value); + saveSettings("ShowRunOption", value); } }); @@ -20,7 +68,26 @@ app.registerExtension({ defaultValue: true, onChange: (value) => { console.log("Kaytool Set/Get Options display set to:", value); + saveSettings("ShowSetGetOptions", value); } }); + + app.ui.settings.addSetting({ + id: "Kaytool.ShowCustomLogo", + name: "Rename the LOGO file to “logo.(png/jpg/jpeg/ico)” and place it in “/ComfyUI/custom_nodes/kaytool”", + type: "boolean", + defaultValue: true, + options: [ + { value: true, text: "Enabled" }, + { value: false, text: "Disabled" } + ], + onChange: (value) => { + saveSettings("ShowCustomLogo", value); + updateFavicon(); + } + }); + + await loadSettings(); + await updateFavicon(); } }); \ No newline at end of file