Skip to content

Commit

Permalink
Merge pull request #83 from shadowcz007/v0.6---simple-app
Browse files Browse the repository at this point in the history
V0.6   simple app
  • Loading branch information
shadowcz007 authored Dec 27, 2023
2 parents c9a598f + 2d336af commit 8304372
Show file tree
Hide file tree
Showing 15 changed files with 1,226 additions and 68 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
__pycache__/
https/
nodes/config.json
workflow/my_workflow.json
workflow/my_workflow.json
workflow/my_workflow_app.json
28 changes: 13 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
##
v0.5.0 🚀🚗🚚🏃‍
- Added video composition support to the MergeLayers.
- Enhanced visual selection support for the NewLayer node.
- Introduced the NoiseImage node and ResizeImage node.
- Improved compatibility for TextImage with line breaks.
- Optimized the 3DImage node to export textures for modification.
- [Added DynamicDelayByText, enabling delayed execution based on input text length.](./workflow/audio-chatgpt-workflow.json)

v0.6.0 🚀🚗🚚🏃‍ Workflow-to-APP
- 新增AppInfo节点,可以通过简单的配置,把workflow转变为一个Web APP。
- Add the AppInfo node, which allows you to transform the workflow into a web app by simple configuration.

- 为MergeLayers添加了视频合成功能。
- NewLayer节点增加了视觉选择支持。
- 添加了NoiseImage节点和ResizeImage节点。
- 支持带有换行的文本图像。
- 对3D节点进行了优化,支持导出纹理以进行修改。
- [添加了DynamicDelayByText功能,可以根据输入文本的长度进行延迟执行。](./workflow/audio-chatgpt-workflow.json)
![](./assets/appinfo-readme.png)
Example:
- workflow
![APP info](./workflow/appinfo-workflow.svg)

APP-JSON:
- [text-to-image](./app/text-to-image_1_Wed%20Dec%2027%202023.json)
- [image-to-image](./app/image-to-image_1_Wed%20Dec%2027%202023.json)

### 3D
![](./assets/3dimage.png)
Expand Down Expand Up @@ -66,7 +62,9 @@ https://github.com/shadowcz007/comfyui-mixlab-nodes/assets/12645064/e7e77f90-e43
## Utils
> The Color node provides a color picker for easy color selection, the Font node offers built-in font selection for use with TextImage to generate text images, and the DynamicDelayByText node allows delayed execution based on the length of the input text.
- [添加了DynamicDelayByText功能,可以根据输入文本的长度进行延迟执行。](./workflow/audio-chatgpt-workflow.json)

- [Added DynamicDelayByText, enabling delayed execution based on input text length.](./workflow/audio-chatgpt-workflow.json)

## Other Nodes

Expand Down Expand Up @@ -104,7 +102,7 @@ Add edges to an image.
### Improvement

- Add "help" option to the context menu for each node.
- Add "find the node" option to the global context menu.
- Add "Nodes Map" option to the global context menu.

An improvement has been made to directly redirect to GitHub to search for missing nodes when loading the graph.

Expand Down
48 changes: 46 additions & 2 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,29 @@ def get_workflows():
workflows=read_workflow_json_files(workflow_path)
return workflows

def get_my_workflow_for_app():
# print("#####path::", current_path)
workflow_path=os.path.join(current_path, "workflow/my_workflow_app.json")
print('workflow_path: ',workflow_path)
json_data={}
try:
with open(workflow_path) as json_file:
json_data = json.load(json_file)
except:
print('-')
return json_data

def save_workflow_json(data):
workflow_path=os.path.join(current_path, "workflow/my_workflow.json")
with open(workflow_path, 'w') as file:
json.dump(data, file)
return workflow_path

def save_workflow_for_app(data):
workflow_path=os.path.join(current_path, "workflow/my_workflow_app.json")
with open(workflow_path, 'w') as file:
json.dump(data, file)
return workflow_path

def get_nodes_map():
# print("#####path::", current_path)
Expand Down Expand Up @@ -253,6 +270,18 @@ async def mixlab_hander(request):
print(e)
return web.json_response(data)


@routes.get('/mixlab/app')
async def mixlab_app_handler(request):
html_file = os.path.join(current_path, "web/index.html")
if os.path.exists(html_file):
with open(html_file, 'r') as f:
html_data = f.read()
return web.Response(text=html_data, content_type='text/html')
else:
return web.Response(text="HTML file not found", status=404)


@routes.post('/mixlab/workflow')
async def mixlab_workflow_hander(request):
data = await request.json()
Expand All @@ -265,6 +294,17 @@ async def mixlab_workflow_hander(request):
'status':'success',
'file_path':file_path
}
elif data['task']=='save_app':
file_path=save_workflow_for_app(data['data'])
result={
'status':'success',
'file_path':file_path
}
elif data['task']=='my_app':
result={
'data':get_my_workflow_for_app(),
'status':'success',
}
elif data['task']=='list':
result={
'data':get_workflows(),
Expand All @@ -289,6 +329,7 @@ async def nodes_map_hander(request):

return web.json_response(result)

# 把插件自定义的路由添加到comfyui server里
def new_add_routes(self):
import nodes
self.app.add_routes(routes)
Expand Down Expand Up @@ -324,12 +365,13 @@ def new_add_routes(self):
from .nodes.Clipseg import CLIPSeg,CombineMasks
from .nodes.ChatGPT import ChatGPTNode,ShowTextForGPT,CharacterInText
from .nodes.Audio import GamePal,SpeechRecognition,SpeechSynthesis
from .nodes.Utils import ColorInput,FontInput,TextToNumber,DynamicDelayProcessor
from .nodes.Utils import AppInfo,FloatSlider,ColorInput,FontInput,TextToNumber,DynamicDelayProcessor


# 要导出的所有节点及其名称的字典
# 注意:名称应全局唯一
NODE_CLASS_MAPPINGS = {
"AppInfo":AppInfo,
"RandomPrompt":RandomPrompt,
"NoiseImage":NoiseImage,
"TransparentImage":TransparentImage,
Expand Down Expand Up @@ -360,6 +402,7 @@ def new_add_routes(self):
"SpeechRecognition":SpeechRecognition,
"SpeechSynthesis":SpeechSynthesis,
"Color":ColorInput,
"FloatSlider":FloatSlider,
"Font":FontInput,
"TextToNumber":TextToNumber,
"DynamicDelayProcessor":DynamicDelayProcessor
Expand All @@ -368,7 +411,8 @@ def new_add_routes(self):

# 一个包含节点友好/可读的标题的字典
NODE_DISPLAY_NAME_MAPPINGS = {
"ResizeImageMixlab":"ResizeImage",
"AppInfo":"AppInfo ♾️Mixlab",
"ResizeImageMixlab":"ResizeImage ♾️Mixlab",
"RandomPrompt": "Random Prompt ♾️Mixlab",
"SplitLongMask":"Splitting a long image into sections",
"VAELoaderConsistencyDecoder":"Consistency Decoder Loader",
Expand Down
1 change: 1 addition & 0 deletions app/image-to-image_1_Wed Dec 27 2023.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions app/text-to-image_1_Wed Dec 27 2023.json

Large diffs are not rendered by default.

Binary file added assets/appinfo-readme.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/appinfo-readme2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 7 additions & 5 deletions data/extension-node-map.json
Original file line number Diff line number Diff line change
Expand Up @@ -4762,15 +4762,15 @@
"https://github.com/shadowcz007/comfyui-mixlab-nodes": [
[
"3DImage",
"AppInfo",
"ResizeImage",
"NoiseImage",
"AreaToMask",
"CLIPSeg",
"CLIPSeg_",
"CharacterInText",
"ChatGPTOpenAI",
"Color",
"CombineMasks_",
"CombineSegMasks",
"EmptyLayer",
"EnhanceImage",
"FaceToMask",
"FeatheredMask",
Expand All @@ -4792,10 +4792,12 @@
"TextImage",
"TransparentImage",
"VAEDecodeConsistencyDecoder",
"VAELoaderConsistencyDecoder"
"VAELoaderConsistencyDecoder",
"TextToNumber",
"DynamicDelayProcessor"
],
{
"title_aux": "comfyui-mixlab-nodes [WIP]"
"title_aux": "comfyui-mixlab-nodes"
}
],
"https://github.com/shiimizu/ComfyUI_smZNodes": [
Expand Down
126 changes: 124 additions & 2 deletions nodes/Utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,53 @@
import os
import re,random
from PIL import Image
import numpy as np
# FONT_PATH= os.path.abspath(os.path.join(os.path.dirname(__file__),'../assets/王汉宗颜楷体繁.ttf'))

import folder_paths
import matplotlib.font_manager as fm

# import json
# import hashlib


# def get_json_hash(json_content):
# json_string = json.dumps(json_content, sort_keys=True)
# hash_object = hashlib.sha256(json_string.encode())
# hash_value = hash_object.hexdigest()
# return hash_value



def tensor2pil(image):
return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))


def create_temp_file(image):
output_dir = folder_paths.get_temp_directory()

(
full_output_folder,
filename,
counter,
subfolder,
_,
) = folder_paths.get_save_image_path('tmp', output_dir)


image=tensor2pil(image)

image_file = f"{filename}_{counter:05}.png"

image_path=os.path.join(full_output_folder, image_file)

image.save(image_path,compress_level=4)

return [{
"filename": image_file,
"subfolder": subfolder,
"type": "temp"
}]

def get_font_files(directory):
font_files = {}

Expand Down Expand Up @@ -120,6 +164,35 @@ def run(self,text,random_number,number):
result= random.randint(1, 10000000000)
return {"ui": {"text": [text],"num":[result]}, "result": (result,)}



class FloatSlider:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"number":("FLOAT", {
"default": 0,
"min": 0, #Minimum value
"max": 1, #Maximum value
"step": 0.01, #Slider's step
"display": "slider" # Cosmetic only: display as "number" or "slider"
}),
},
}

RETURN_TYPES = ("FLOAT",)

FUNCTION = "run"

CATEGORY = "♾️Mixlab/utils"

INPUT_IS_LIST = False
OUTPUT_IS_LIST = (False,)

def run(self,number):

return (number,)

# 接收一个值,然后根据字符串或数值长度计算延迟时间,用户可以自定义延迟"字/s",延迟之后将转化

import comfy.samplers
Expand All @@ -141,7 +214,7 @@ class DynamicDelayProcessor:

@classmethod
def INPUT_TYPES(cls):
print("print INPUT_TYPES",cls)
# print("print INPUT_TYPES",cls)
return {
"required":{
"delay_seconds":("INT",{
Expand Down Expand Up @@ -210,3 +283,52 @@ def run(self,any_input,delay_seconds,delay_by_text,words_per_seconds,replace_out
# 根据 replace_output 决定输出值
return (max(0, replace_value),) if replace_output == "enable" else (any_input,)




# app 配置节点
class AppInfo:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"name": ("STRING",{"multiline": False,"default": "Mixlab-App"}),
"image": ("IMAGE",),
"input_ids":("STRING",{"multiline": True,"default": "\n".join(["1","2","3"])}),
"output_ids":("STRING",{"multiline": True,"default": "\n".join(["5","9"])}),
},

"optional":{
"description":("STRING",{"multiline": True,"default": ""}),
"version":("INT", {
"default": 1,
"min": 1,
"max": 10000,
"step": 1,
"display": "number"
}),
}

}

RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("IMAGE",)

FUNCTION = "run"

CATEGORY = "♾️Mixlab"

INPUT_IS_LIST = False
OUTPUT_IS_LIST = (False,)

def run(self,name,image,input_ids,output_ids,description,version):

im=create_temp_file(image)

# id=get_json_hash([name,im,input_ids,output_ids,description,version])

return {"ui": {"json": [name,im,input_ids,output_ids,description,version]}, "result": (image,)}





Loading

0 comments on commit 8304372

Please sign in to comment.