diff --git a/README.MD b/README.MD
index bfdaf98..d59be1c 100644
--- a/README.MD
+++ b/README.MD
@@ -12,6 +12,7 @@ Nodes are divided into four groups according to their functions: LayerStyle, Lay
[䏿–‡è¯´æ˜Žç‚¹è¿™é‡Œ](./README_CN.MD)
## Update
+* Add [ExtendCanvas](#ExtendCanvas) node.
* Add [ImageBlendAdvance](#ImageBlendAdvance) node. This node allows for the synthesis of background images and layers of different sizes, providing a more free synthesis experience.
Add [PrintInfo](#PrintInfo) node as a workflow debugging aid.
* Add [GradientOverlay](#GradientOverlay) and [ColorOverlay](#ColorOverlay) nodes.
@@ -248,6 +249,20 @@ Node options:
Output Type:
* string
+### ExtendCanvas
+Extend the canvas
+
+
+Node options:
+
+* invert_mask: Whether to reverse the mask.
+* top: Top extension value.
+* bottom: Bottom extension value.
+* left: Left extension value.
+* right: Right extension value.
+* color; Color of canvas.
+
+
### PrintInfo

Used to provide assistance for workflow debugging. When running, the properties of any object connected to this node will be printed to the console.
@@ -301,7 +316,7 @@ LayerMask:
* mask softedge
LayerFilter:
-* bulr
+* blur
* emboss
* contour
* findedge
diff --git a/README_CN.MD b/README_CN.MD
index b365e88..3d15b16 100644
--- a/README_CN.MD
+++ b/README_CN.MD
@@ -9,6 +9,7 @@ ComfyUI
* [LayerFilter](#LayerFilter)½Úµã×éÌṩͼÏñЧ¹ûÂ˾µ¡£
## ¸üÐÂ˵Ã÷
+* Ìí¼Ó[ExtendCanvas](#ExtendCanvas)½Úµã¡£
* Ìí¼Ó[ImageBlendAdvance](#ImageBlendAdvance)½Úµã¡£Õâ¸ö½ÚµãÔÊÐíºÏ³É³ß´ç²»Í¬µÄ±³¾°Í¼ºÍͼ²ã£¬ÌṩÁ˸ü¼Ó×ÔÓɵĺϳÉÌåÑé¡£
Ìí¼Ó[PrintInfo](#PrintInfo)½Úµã×÷Ϊ¹¤×÷Á÷µ÷ÊÔ¸¨Öú¹¤¾ß¡£
* Ìí¼Ó[GradientOverlay](#GradientOverlay),[ColorOverlay](#ColorOverlay)½Úµã¡£Ôö¼ÓÎÞЧmaskÊäÈëÅжϣ¬µ±ÊäÈëÎÞЧmaskʱ½«ÆäºöÂÔ¡£
@@ -245,6 +246,20 @@ mask
Êä³ö:
* string
+### ExtendCanvas
+À©Õ¹»²¼¡£
+
+
+½ÚµãÑ¡Ïî˵Ã÷:
+
+* invert_mask: ÊÇ·ñ·´×ªÕÚÕÖ¡£
+* top: ¶¥²¿À©Õ¹Öµ¡£
+* bottom: µ×²¿À©Õ¹Öµ¡£
+* left: ×ó²àÀ©Õ¹Öµ¡£
+* right: ÓÒ²àÀ©Õ¹Öµ¡£
+* color; »²¼ÑÕÉ«
+
+
### PrintInfo

ÓÃÓÚ¸ø¹¤×÷Á÷µ÷ÊÔÌṩ¸¨Öú¡£µ±ÔËÐÐʱ£¬ÈκνÓÉÏÕâ¸ö½ÚµãµÄ¶ÔÏóµÄÊôÐÔ½«±»´òÓ¡µ½¿ØÖÆÌ¨¡£
@@ -294,7 +309,7 @@ LayerMask:
* mask softedge
LayerFilter:
-* bulr
+* blur
* emboss
* contour
* findedge
diff --git a/image/extend_canvas_example.png b/image/extend_canvas_example.png
new file mode 100644
index 0000000..cc65b2e
Binary files /dev/null and b/image/extend_canvas_example.png differ
diff --git a/image/extend_canvas_node.png b/image/extend_canvas_node.png
new file mode 100644
index 0000000..2dc01e5
Binary files /dev/null and b/image/extend_canvas_node.png differ
diff --git a/py/color_picker.py b/py/color_picker.py
index 742d862..4734b96 100644
--- a/py/color_picker.py
+++ b/py/color_picker.py
@@ -13,7 +13,7 @@ class ColorPicker:
return {
"required": {
- "color": ("COLOR", {"default": "white"},),
+ "color": ("COLOR", {"default": "#FFFFFF"},),
"mode": (mode_list,), # 输出模�
},
"optional": {
diff --git a/py/extand_canvas.py b/py/extand_canvas.py
new file mode 100644
index 0000000..73521a7
--- /dev/null
+++ b/py/extand_canvas.py
@@ -0,0 +1,62 @@
+from .imagefunc import *
+
+class ExtendCanvas:
+
+ def __init__(self):
+ pass
+
+ @classmethod
+ def INPUT_TYPES(self):
+
+ return {
+ "required": {
+ "image": ("IMAGE", ),
+ "invert_mask": ("BOOLEAN", {"default": True}), # �转mask
+ "top": ("INT", {"default": 0, "min": 0, "max": 99999, "step": 1}),
+ "bottom": ("INT", {"default": 0, "min": 0, "max": 99999, "step": 1}),
+ "left": ("INT", {"default": 0, "min": 0, "max": 99999, "step": 1}),
+ "right": ("INT", {"default": 0, "min": 0, "max": 99999, "step": 1}),
+ "color": ("COLOR", {"default": "#000000"},),
+ },
+ "optional": {
+ "mask": ("MASK",), #
+ }
+ }
+
+ RETURN_TYPES = ("IMAGE", "MASK",)
+ RETURN_NAMES = ("image", "mask")
+ FUNCTION = 'extend_canvas'
+ CATEGORY = '😺dzNodes/LayerUtility'
+ OUTPUT_NODE = True
+
+ def extend_canvas(self, image, invert_mask,
+ top, bottom, left, right, color,
+ mask=None,
+ ):
+
+ _image = tensor2pil(image).convert('RGB')
+ _mask = tensor2pil(image).convert('RGBA').split()[-1]
+ if mask is not None:
+ if invert_mask:
+ mask = 1 - mask
+ _mask = mask2image(mask).convert('L')
+
+ width = _image.width + left + right
+ height = _image.height + top + bottom
+ _canvas = Image.new('RGB', (width, height), color)
+ _mask_canvas = Image.new('L', (width, height), "black")
+
+ _canvas.paste(_image, box=(left,top))
+ _mask_canvas.paste(_mask.convert('L'), box=(left, top))
+ ret_image = _canvas
+ ret_mask = image2mask(_mask_canvas)
+ log('ExtendCanvas Processed.')
+ return (pil2tensor(ret_image), ret_mask,)
+
+NODE_CLASS_MAPPINGS = {
+ "LayerUtility: ExtendCanvas": ExtendCanvas
+}
+
+NODE_DISPLAY_NAME_MAPPINGS = {
+ "LayerUtility: ExtendCanvas": "LayerUtility: ExtendCanvas"
+}
\ No newline at end of file
diff --git a/workflow/extend_canvas_example.json b/workflow/extend_canvas_example.json
new file mode 100644
index 0000000..8de1f2f
--- /dev/null
+++ b/workflow/extend_canvas_example.json
@@ -0,0 +1,194 @@
+{
+ "last_node_id": 29,
+ "last_link_id": 62,
+ "nodes": [
+ {
+ "id": 29,
+ "type": "LayerUtility: ExtendCanvas",
+ "pos": [
+ 750,
+ 450
+ ],
+ "size": {
+ "0": 218.39999389648438,
+ "1": 210
+ },
+ "flags": {},
+ "order": 1,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "image",
+ "type": "IMAGE",
+ "link": 59
+ },
+ {
+ "name": "mask",
+ "type": "MASK",
+ "link": 60
+ }
+ ],
+ "outputs": [
+ {
+ "name": "image",
+ "type": "IMAGE",
+ "links": [
+ 61
+ ],
+ "shape": 3,
+ "slot_index": 0
+ },
+ {
+ "name": "mask",
+ "type": "MASK",
+ "links": [
+ 62
+ ],
+ "shape": 3,
+ "slot_index": 1
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "LayerUtility: ExtendCanvas"
+ },
+ "widgets_values": [
+ true,
+ 80,
+ 59,
+ 135,
+ 112,
+ "#8a0000"
+ ]
+ },
+ {
+ "id": 28,
+ "type": "LayerMask: MaskPreview",
+ "pos": [
+ 1080,
+ 590
+ ],
+ "size": [
+ 263.00006103515625,
+ 262.6666259765625
+ ],
+ "flags": {},
+ "order": 3,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "mask",
+ "type": "MASK",
+ "link": 62
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "LayerMask: MaskPreview"
+ }
+ },
+ {
+ "id": 26,
+ "type": "PreviewImage",
+ "pos": [
+ 1080,
+ 290
+ ],
+ "size": {
+ "0": 264.4000244140625,
+ "1": 246
+ },
+ "flags": {},
+ "order": 2,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "images",
+ "type": "IMAGE",
+ "link": 61
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "PreviewImage"
+ }
+ },
+ {
+ "id": 23,
+ "type": "LoadImage",
+ "pos": [
+ 380,
+ 450
+ ],
+ "size": {
+ "0": 315,
+ "1": 314
+ },
+ "flags": {},
+ "order": 0,
+ "mode": 0,
+ "outputs": [
+ {
+ "name": "IMAGE",
+ "type": "IMAGE",
+ "links": [
+ 59
+ ],
+ "shape": 3,
+ "slot_index": 0
+ },
+ {
+ "name": "MASK",
+ "type": "MASK",
+ "links": [
+ 60
+ ],
+ "shape": 3,
+ "slot_index": 1
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "LoadImage"
+ },
+ "widgets_values": [
+ "ComfyUI_00193_ (5).png",
+ "image"
+ ]
+ }
+ ],
+ "links": [
+ [
+ 59,
+ 23,
+ 0,
+ 29,
+ 0,
+ "IMAGE"
+ ],
+ [
+ 60,
+ 23,
+ 1,
+ 29,
+ 1,
+ "MASK"
+ ],
+ [
+ 61,
+ 29,
+ 0,
+ 26,
+ 0,
+ "IMAGE"
+ ],
+ [
+ 62,
+ 29,
+ 1,
+ 28,
+ 0,
+ "MASK"
+ ]
+ ],
+ "groups": [],
+ "config": {},
+ "extra": {},
+ "version": 0.4
+}
\ No newline at end of file