diff --git a/README.en.md b/README.en.md index 26b8b52..12d44b4 100644 --- a/README.en.md +++ b/README.en.md @@ -31,6 +31,10 @@ After installing the node package, the UI interface will be automatically switch **2024-02-02** +- `easy showAnything` Added support for converting other types (e.g., tensor conditions, images, etc.) + +**2024-02-02** + - Fixed xyplot replace getfont with getbbox to be compatible with Pillow>9.5 **2024-01-31** diff --git a/README.md b/README.md index 6ebd32d..53706f6 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,10 @@ ## 更新日志 +**2024-02-03** + +- `easy showAnything` 增加支持转换其他类型(如:tensor类型的条件、图像等) + **2024-02-02** - 修改 xyplot 中 getsize 方法为 getbbox 以兼容 pillow>9.5 diff --git a/py/adv_encode.py b/py/adv_encode.py index bce3953..e04a785 100644 --- a/py/adv_encode.py +++ b/py/adv_encode.py @@ -258,7 +258,7 @@ def prepareXL(embs_l, embs_g, pooled, clip_balance): def advanced_encode(clip, text, token_normalization, weight_interpretation, w_max=1.0, clip_balance=.5, - apply_to_pooled=True): + apply_to_pooled=True, width=1024, height=1024, crop_w=0, crop_h=0, target_width=1024, target_height=1024): tokenized = clip.tokenize(text, return_word_ids=True) if isinstance(clip.cond_stage_model, (SDXLClipModel, SDXLRefinerClipModel, SDXLClipG)): embs_l = None @@ -280,17 +280,21 @@ def advanced_encode(clip, text, token_normalization, weight_interpretation, w_ma w_max=w_max, return_pooled=True, apply_to_pooled=apply_to_pooled) - return prepareXL(embs_l, embs_g, pooled, clip_balance) + + embeddings_final, pooled = prepareXL(embs_l, embs_g, pooled, clip_balance) + + return [[embeddings_final, {"pooled_output": pooled, "width": width, "height": height, "crop_w": crop_w, "crop_h": crop_h, "target_width": target_width, "target_height": target_height}]] else: - return advanced_encode_from_tokens(tokenized['l'], + embeddings_final, pooled = advanced_encode_from_tokens(tokenized['l'], token_normalization, weight_interpretation, lambda x: (clip.encode_from_tokens({'l': x}), None), w_max=w_max) + return [[embeddings_final, {"pooled_output": pooled}]] def advanced_encode_XL(clip, text1, text2, token_normalization, weight_interpretation, w_max=1.0, clip_balance=.5, - apply_to_pooled=True): + apply_to_pooled=True,width=1024, height=1024, crop_w=0, crop_h=0, target_width=1024, target_height=1024): tokenized1 = clip.tokenize(text1, return_word_ids=True) tokenized2 = clip.tokenize(text2, return_word_ids=True) @@ -313,4 +317,8 @@ def advanced_encode_XL(clip, text1, text2, token_normalization, weight_interpret repeat_l = int((embs_g.shape[1] / gcd_num) * embs_l.shape[1]) repeat_g = int((embs_l.shape[1] / gcd_num) * embs_g.shape[1]) - return prepareXL(embs_l.expand((-1, repeat_l, -1)), embs_g.expand((-1, repeat_g, -1)), pooled, clip_balance) \ No newline at end of file + embeddings_final, pooled = prepareXL(embs_l.expand((-1, repeat_l, -1)), embs_g.expand((-1, repeat_g, -1)), pooled, clip_balance) + + return [[embeddings_final, + {"pooled_output": pooled, "width": width, "height": height, "crop_w": crop_w, "crop_h": crop_h, + "target_width": target_width, "target_height": target_height}]] \ No newline at end of file diff --git a/py/easyNodes.py b/py/easyNodes.py index 52c6a4d..534fcde 100644 --- a/py/easyNodes.py +++ b/py/easyNodes.py @@ -1748,11 +1748,10 @@ class latentCompositeMaskedWithCond: else: raise Exception(f"[ERROR] To use clip text encode same as webui, you need to install 'smzNodes'") else: - positive_embeddings_final, positive_pooled = advanced_encode(clip, positive, + positive_embeddings_final = advanced_encode(clip, positive, positive_token_normalization, positive_weight_interpretation, w_max=1.0, apply_to_pooled='enable') - positive_embeddings_final = [[positive_embeddings_final, {"pooled_output": positive_pooled}]] # source cond (cond_1,) = ConditioningSetMask().append(positive_cond, source_mask, "default", 1) @@ -1974,15 +1973,13 @@ class fullLoader: else: raise Exception(f"[ERROR] To use clip text encode same as webui, you need to install 'smzNodes'") else: - positive_embeddings_final, positive_pooled = advanced_encode(clipped, positive, positive_token_normalization, + positive_embeddings_final = advanced_encode(clipped, positive, positive_token_normalization, positive_weight_interpretation, w_max=1.0, apply_to_pooled='enable') - positive_embeddings_final = [[positive_embeddings_final, {"pooled_output": positive_pooled}]] - negative_embeddings_final, negative_pooled = advanced_encode(clipped, negative, negative_token_normalization, + negative_embeddings_final = advanced_encode(clipped, negative, negative_token_normalization, negative_weight_interpretation, w_max=1.0, apply_to_pooled='enable') - negative_embeddings_final = [[negative_embeddings_final, {"pooled_output": negative_pooled}]] image = easySampler.pil2tensor(Image.new('RGB', (1, 1), (0, 0, 0))) log_node_warn("处理结束...") @@ -1990,7 +1987,7 @@ class fullLoader: "positive": positive_embeddings_final, "negative": negative_embeddings_final, "vae": vae, - "clip": clip, + "clip": clipped, "samples": samples, "images": image, @@ -5406,8 +5403,8 @@ NODE_DISPLAY_NAME_MAPPINGS = { "easy XYInputs: NegativeCond": "XY Inputs: NegCond //EasyUse", "easy XYInputs: NegativeCondList": "XY Inputs: NegCondList //EasyUse", # others 其他 - "easy showSpentTime": "ShowSpentTime", - "easy showLoaderSettingsNames": "ShowLoaderSettingsNames", + "easy showSpentTime": "Show Spent Time", + "easy showLoaderSettingsNames": "Show Loader Settings Names", "easy imageRemoveBG": "ImageRemoveBG", "dynamicThresholdingFull": "DynamicThresholdingFull", # __for_testing 测试 diff --git a/py/logic.py b/py/logic.py index cf8f0da..6f05bb1 100644 --- a/py/logic.py +++ b/py/logic.py @@ -2,6 +2,7 @@ from typing import Iterator, List, Tuple, Dict, Any, Union, Optional from _decimal import Context, getcontext from decimal import Decimal import numpy as np +import json def validate_list_args(args: Dict[str, List[Any]]) -> Tuple[bool, Optional[str], Optional[str]]: """ @@ -401,7 +402,7 @@ class ConvertAnything: return (params,) # 将所有类型的内容都转成字符串输出 -class ShowAnything: +class showAnything: @classmethod def INPUT_TYPES(s): return {"required": {}, "optional": {"anything": (AlwaysEqualProxy("*"), {}), }, @@ -415,13 +416,27 @@ class ShowAnything: CATEGORY = "EasyUse/Logic" def log_input(self, unique_id=None, extra_pnginfo=None, **kwargs): - print(kwargs['anything']) + + values = [] + if "anything" in kwargs: + for val in kwargs['anything']: + try: + if type(val) is str: + values.append(val) + else: + val = json.dumps(val) + values.append(str(val)) + except Exception: + values.append(str(val)) + pass + if unique_id and extra_pnginfo and "workflow" in extra_pnginfo[0]: workflow = extra_pnginfo[0]["workflow"] node = next((x for x in workflow["nodes"] if str(x["id"]) == unique_id[0]), None) if node: - node["widgets_values"] = [kwargs['anything']] - return {"ui": {"text": kwargs['anything']}} + node["widgets_values"] = [values] + + return {"ui": {"text": values}} NODE_CLASS_MAPPINGS = { "easy string": String, @@ -435,7 +450,7 @@ NODE_CLASS_MAPPINGS = { "easy if": If, "easy xyAny": xyAny, "easy convertAnything": ConvertAnything, - "easy showAnything": ShowAnything, + "easy showAnything": showAnything, } NODE_DISPLAY_NAME_MAPPINGS = { "easy string": "String", @@ -448,6 +463,6 @@ NODE_DISPLAY_NAME_MAPPINGS = { "easy imageSwitch": "Image Switch", "easy if": "If", "easy xyAny": "XYAny", - "easy convertAnything": "ConvertAnything", - "easy showAnything": "ShowAnything" + "easy convertAnything": "Convert Any", + "easy showAnything": "Show Any", } \ No newline at end of file diff --git a/web/js/easy/easyDynamicWidgets.js b/web/js/easy/easyDynamicWidgets.js index 7a408d6..692732d 100644 --- a/web/js/easy/easyDynamicWidgets.js +++ b/web/js/easy/easyDynamicWidgets.js @@ -531,7 +531,7 @@ app.registerExtension({ Object.assign(fileInput, { type: "file", accept: "text/csv", - style: "display: none", + style: "show: none", onchange: async (event) => { if (fileInput.files.length) { await uploadFile(fileInput.files[0], true); @@ -572,7 +572,7 @@ app.registerExtension({ } } - // When the node is executed we will be sent the input text, display this in the widget + // When the node is executed we will be sent the input text, show this in the widget const onExecuted = nodeType.prototype.onExecuted; nodeType.prototype.onExecuted = function (message) { onExecuted?.apply(this, arguments); @@ -592,7 +592,7 @@ app.registerExtension({ } } - // When the node is executed we will be sent the input text, display this in the widget + // When the node is executed we will be sent the input text, show this in the widget const onExecuted = nodeType.prototype.onExecuted; nodeType.prototype.onExecuted = function (message) { onExecuted?.apply(this, arguments);