From 6c3bdf2d2414a00498816df5f8d89f13558810bb Mon Sep 17 00:00:00 2001 From: chflame163 <130118553+chflame163@users.noreply.github.com> Date: Thu, 18 Jan 2024 20:45:28 +0800 Subject: [PATCH] layer_mask is not a mandatory input --- README.MD | 2 + README_CN.MD | 2 + py/__pycache__/drop_shadow.cpython-311.pyc | Bin 3108 -> 3356 bytes py/__pycache__/image_blend.cpython-311.pyc | Bin 0 -> 2472 bytes py/__pycache__/imagefunc.cpython-311.pyc | Bin 9079 -> 9079 bytes py/__pycache__/outer_glow.cpython-311.pyc | Bin 2842 -> 3098 bytes py/drop_shadow.py | 31 ++++++----- py/image_blend.py | 59 +++++++++++++++++++++ py/imagefunc.py | 1 - py/outer_glow.py | 23 ++++---- 10 files changed, 93 insertions(+), 25 deletions(-) create mode 100644 py/__pycache__/image_blend.cpython-311.pyc create mode 100644 py/image_blend.py diff --git a/README.MD b/README.MD index 15452ae..3edc113 100644 --- a/README.MD +++ b/README.MD @@ -7,6 +7,8 @@ Currently completed Drop Shadow and OuterGlow nodes, and follow-up work is in pr [中文说明点这里](./README_CN.MD) ## Update +* Now, layer_mask is not a mandatory input. without inputting will use the layer_image's alpha channel. It is allowed to use layers and masks with different shapes, but the size must be consistent. +![image](image/title.png) * Commit ImageBlend node. * Remove the mask channel output from the DropShadow node; Commit OuterGlow node. * Commit DropShadow node. diff --git a/README_CN.MD b/README_CN.MD index 9bf7f1c..6501ede 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -3,6 +3,8 @@ ComfyUI µ±Ç°ÒÑÍê³ÉDrop ShadowºÍOuterGlow½Úµã£¬ºóÐø¹¤×÷½øÐÐÖС£ ## ¸üÐÂ˵Ã÷£º +* ÏÖÔÚlayer_mask²»ÊÇÊäÈë±ØÑ¡¡£²»ÊäÈ뽫ʹÓÃlayer_imageµÄalphaͨµÀ¡£ÔÊÐíʹÓÃÐÎ×´²»Í¬µÄlayerºÍmask£¬µ«ÊÇ³ß´ç±ØÐëÒ»Ö¡£ +![image](image/title.png) * Ìí¼ÓImageBlend½Úµã * DropShadow½ÚµãÈ¥µôµ÷ÊÔmaskͨµÀÊä³ö£»Ìí¼ÓOuterGlow½Úµã¡£ * DropShadow½ÚµãÉÏÏß¡£ diff --git a/py/__pycache__/drop_shadow.cpython-311.pyc b/py/__pycache__/drop_shadow.cpython-311.pyc index f8f4174add1f41f7087fdb0b9af890f6ae1a0a5c..ce405c7f50682b5d7954dd4baed572555974d3f9 100644 GIT binary patch delta 1701 zcmahJTTC2P^xoOsc``6F``}F$S^~TDfk+^xr5h?Jq0&T2G|{B%hP%MF3xl&m8=AX8 z6CW!-f;W-X@Ii=x=0s%Pe&d(NEKy=Trj zpVzH5$Y08`2q-)Z-AjJABHw`{EAI^`0ze`X-i5DAh#vY?k` z_bFNhQvksYn1zU;j|X{?F9jzV3@0IC5r=prP(RX|caoue6_Qc)fABRY1JLgA2PF0B!4nta@I3G>WJyYLehxOBr>-m(D9B9j$ex~ z4sRsinok)?-NWS)*hu@MPJoV%c z&j(#WslK`hT+{&6=6tH?VJO|GC}I(mksumX)Yb@*4R17ZeZpmqfTct!e_o1L0cItT zWidxFN3O6<%sM10=YNK#brS-xO;;JRRpv1b0A?zsPqmW&-^vfrNpFmMhB2^7LvJ4) z03c8OF`cc((mN6CF?`62rMt9%vXaRiivgBSJ0Iy{wZ&@8BKDS>0+68>KcWrQbo2ih zFxA4`Ce_+5X}X`YHKueV2f&n{(72{D8s@Qp*iA3BrmGBD#dJ#-5QS}yK`h@qj)ujZ zlaa)VtSOb=%ei*%5>d_IWA}8!RanGc>^l)x!&U2&o6kmoHLULNo3yUB-P$Svq;_Tb zBET}PK24tWn@>^?u)p#=laO|RaNY5|^5Rv;OVQxZe^W5r5Dt9FXreo90N;e3)(y84 zN*y6PqM4k{=tj?6D(!F+`mA(2X_$^LGnY=8QZpsm5sai6Pt7Ezl4OZ*VBG;@^pUUl@M4Bm@!Oy% zg4)*QH*(@ZDC};BTGMXxc}u%sYZvylzCEq4FmGuCwlg} zgP-Yn{V*6_4{nKtQ7ag;gR$HThoROlqFb+8ZM}9|ZvovOdeCZxhV0N#PWqh%brJK$?Rl9%M=srBKUZ1GW>kM8o( zA`1kC{3z5lQ&%(x&sj>lt+emfbnNmS2nkBj<>RY=|A{f)v`9Er>FY24GM$w3>EspT sP3p`YP?;%;iXI5z0jS$OdW+tx5K`x-<6lbOfBUy|lsuB!z3$-r2XMcSB>(^b delta 1492 zcmaJ>O=ufO6yDh%X?9mXs~^j;V%dsY$ChY(i0Wdesa-b?g{BRpPN29kLTKcl#J0lj zHlbmJdPwP#OJn9>wYVTc;~MNkpqE?%IrdV}hJ}g+L0TyEsFJ3TUeX!Ka*-4IcK6$P zGxNUp=IwjC761N-{|CQc;i&xf$4+5k!+!(JZhZNU55Zg9yo%&GE~RWdegmX7UfeAQ z={A8rPj6A!oRb@5zc|p&v<&3MO zN4Q8zLhqoLhMnSdNMEj;UoKwDt`$+i;HjQW>N5FJH~}7#Uxhw?V1zsutk-*eeSs#& zAPy)bG)-x8ZIBgRrFMD`*%Q;{ypN7M;-Q09nlNSFvGa1LeVByfJAA1phwY9_W;4=t1?um!|s$Itow0)7E zJ%i+3j|PI|h1ee`X=bEN*`lRWajaqqdk#er!dg`!IVqaPAspQEY|~8dvhUauz;(IW z&t1or6zmw6vF}yJSSy8bpcFBCJA^bh;qKfl0$P0D^E&gX_fv3%kKccf)}fRyt`>C{ ze8_5&RbR^IDrRBbDC#G#t*p8Vn>)F(mRl;gChmsCdJb^@5pg6F@d(ghrHxkbH&c?EC8Dz%qfThl@-(z~<&>=*ceLY{R9AZ{ zq1)5ebmhv<%(ul#u@N1tO4Xb9PubBaCpu-FZN!ew*UYD diff --git a/py/__pycache__/image_blend.cpython-311.pyc b/py/__pycache__/image_blend.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e2f277ce402d1f951ce9250270464d88a9f87be GIT binary patch literal 2472 zcmbVNO-vg{6rQ!cKVI8m4Td&^A15gS)09xEhBggN9pVr-U??_+xTveevnE#jm)&(# zkddgw!Rn>CL8VAVJZ+E_#dGmJO zn>X*h{l()E5ztp1o9f>jLVwapgB%Bg{ZC-9iZH@V8pV(ejUjAXLD;@wLud<{MR5i@ zR3^p5ZPD$Q*~oBmq{+ngl8LlqM#eOjGWD3Rc|omab-c( zqQ*j6oy{-Irl@v#j;bHXFAzbNQ`wXu%Zn{Xb`3O`EU46ZfMrw@+$G084ABXz>Ft}i{03hV(^*AHtF!knQg34@3@l}xIdnoX#L!-{ra)d-(X&EGRr zZIdBvcp^9!BK(cX$?;GyLU^nu71%LG?BPgk4}-0H(2zziIpEOFLPzYG6zIt)--5pl zH6LJ!G^Zr)&uh6t7R#pJh$~H<*_foV4^_>OGm3tnh^9;B47i@~xxA7{84Ex&p9_Uijw9=38>sIn*;)>kho|2cCqtjq>}~%H1Qi?!L8jt>gR? z{pp9#qUGsm`C^Q|=Vt02{_L4LqR@=IoolJO-3H?pw!i*kL#t_o z*r&&C5C=eT?;jvD#|Se{6TnOao`{B;)pOcVJ_VVc$eCG0SUsOkL1t5#AuFClGZCyY zn^zz!i3r~eS)T{oX1Zv8FiAU4;R1z=6yBrI13-8=p=2K_I^kq983}9UD=Q~*nLKf7 zs$r$GP6OJ1jLfXlE&=yMwjGP{ZdlX*09Zz^MAXt*?);$AJWy>O*loVD(|l#SP-z~i zHjk9}=iYN`cPie#s<&^~JGkQ=+-|LShpXP<68BtcU;C^g^;V_cUFq_Uba|VrNW)cW zcvl+Pkwz-g^{RCJnXM{~me`uBwd^`yYih3}#&fCG*|pyO<2R4Q=f1AB#fq=L>g(V2 z4ej`bwm+))hO55eQs@GPrs?b*! z`k+X(c9fjdo=+=MPgUwEH}#fxsw@*xrWLA?ren7(KPV_^Yel1p zPh5$#qU#yexR=9PKjpZmL$R6Zh*iH1XOZAUC`yD|Gm+6)crrqS(O@hzHaUHlxF%;} zwBAJ~Z-&fUFl(e`4XuY74P6sx9nm#_<-@1$U|0`$sR10~ymi|d777@^OFK+gzP1>C zrDP$SFpoi6=uzd-@nAG6PXwo?!jZ8kX*ZcS!_len;9Z%z>u~LqLtYEltQ+}U z8wZ1E)zoExx}9N|8hW?fc&j$t|V?ipILMMbKA5+>00L7{rYybcN delta 91 zcmezF_T7zlIWI340}u#bUXfb9k+)Qk@xkV1!R<_pdYi39_w0VE^oYj|5h;tVj9)u-p-=IZl}il4@^ zl>f|9aUaY91iy!6h!}dY$cMNb%rX|tLc}8hiIgQIuluqLT`S0s0xzwD9sVwwt$Nu= zTNhCXb>|?`*BQEd&$J=B{Cp7?(j?4G5gGzT@(VLW{$?)guAEPQnZc<-y7ZX=UEj^g znHwa=hDDKfXfRkJx7c1NlPr6o?>;r%1$+9(jrLuYT09tz?F<^^F?;8{CiMkdz!SYd zi>&2ZEJO8hP?cL?Uq~|c0KmN@<}*%C&$gkX29J2kZDe*BiVS(oMVJjpQe4j%tU&;_ zDDP8QHVH`pU3a%psp8Ez`4=B~v(X z14}yE>7mclNP!Dq^PAG4)l?33%io!8@s@!2nvZrvd7sJwlfp|r;sz(6rF`nWz&2Up zBcVpI-SY5lQ(5f5BhXp9jo~mGG`q<|E?N;SpT!;7smqc#UVeKo3InUl3O*8R6uYeh z{2(|sTCx296P?2%*>aHIKGg}yTWX7ekp@Zmn$vgb0*p4-y#FTAgj^wzAB81LTWZWzmzVK1>tms zOU>nrU$_#^n5kSLJ(nqIbc>;*guV0QI2FtKtwl3~r)bt_(bL)m&QMS3CLPtg;F%wE zM;ejW?a-(b8f}IyZHF$^7wu5e2_>t-u6APWhOLb_+DKE2ZCA8dy~oxPj+UtMyK4X1 z+qN2Y)M!&3+g8Wwysai2HPKX)+iKEQCmeO+XU0*lRk=N-r=gtM>FRF*7`U(#8QAFm z?#?}VS07kgw)Jz4ey*vq*dZK#$SAFoI{NqJ?XxteZufO?3fAYDllPhA9 ztcdX|^y8M)Zv)>1?qxSFRs*(ZIHJ)IjXnKDReHt)+V*8z9d^{=Mpv{UM)$vMZ{mp} zMZ3M>b(PtCx>PD;%uk94$H;YQ@{ETV_GWWGzKtU1Ej{5)XbF=|Y38g922Qtx2shFK y#|Z2vz4CH@XRYVrJB1=z%xB)kx5-cPppk^M!mHwU&-T}$<0?b`kk9(O|I@!Y&_|R2 delta 1225 zcmZ`&%WvF77@zTT#@>f_(}reQl0|g8F^@n9s+#bSS`{Hth(vQh>VcKnagqh^I*i>Q zB3sP?q`ihgYKS5cArUH)OaBZc4%uoYR#qeRf&{lM&`S@%%x+SW27dPU*`NKr^_z_| z8^f9J(`f^6-2LsA`z2n>EW^udU%Z|o=yPz*BzO+k#@e0dpuP6j){QjxlezpsxVi}z z0D<4a7!rwJGEs<1v^t!ZA~+9;P7uLd3}S97^AfjHBuz3$?Ci1s7LU$}Xp-N=bwGwT zC0_f~tc?<_>C=YeC2UN36WK6P-n}??h4GpYvmd3BX?V_OF0D44;A8fyG;`jT5=7lk zuGgtc667z1b-(F&ROe0G5=H!x;M$_URBiag4J2-tN)$6se!j@Ku?p^;`f#s*w{TAb z<(Il+c6YSGZp$B>9Wq8TJs{LDEJBVn18!ZQ}rByU3icDM`>o1uF64nQa-IY49{_l)!i5oufD(Od?I zQ=u6809!{g9ex94K;+2yNc7o9gm;x~-q6mYreYjIc26xxTRPiS%P`GWm7)@7!W`Ss zDh`g+NPDboHp*<_!;D9tQ8r5NYTJAlJ7W8NKoC9}7l6kXFeo~m{@;woe`Sm^u@$A_ zTzHyY(8s3qSt`oWB3Frg^{q>sOKQ#ce44;_1g`{xY%?)Jw;A~K<)ymEzSA!tz2-NU zT^h2xdP&Yx#QxSN*))3kl3uMj&1EM@)arugf0|(GhShq*S#Sjb!#*Q}Jg-(d0V)_Zn|xiJ63rwTiHXEK6z&uG%7=ax`|oyoFHhp;i6CIi|ke7;xm(?XFn`aeq torch.Tensor: def mask2image(mask:torch.Tensor) -> Image: masks = tensor2np(mask) - # images = [] for m in masks: _mask = Image.fromarray(m).convert("L") _image = Image.new("RGBA", _mask.size, color='white') diff --git a/py/outer_glow.py b/py/outer_glow.py index b06baa4..fab82fe 100644 --- a/py/outer_glow.py +++ b/py/outer_glow.py @@ -12,7 +12,6 @@ class OuterGlow: "required": { "background_image": ("IMAGE", ), # "layer_image": ("IMAGE",), # - "layer_mask": ("MASK",), # "invert_mask": ("BOOLEAN", {"default": True}), # å��转mask "blend_mode": (chop_mode,), # æ··å�ˆæ¨¡å¼� "opacity": ("INT", {"default": 100, "min": 0, "max": 100, "step": 1}), # é€�明度 @@ -21,6 +20,7 @@ class OuterGlow: "glow_color": ("STRING", {"default": "#FFFFFF"}), # 背景颜色 }, "optional": { + "layer_mask": ("MASK",), # } } @@ -32,31 +32,34 @@ class OuterGlow: CATEGORY = '😺dzNodes' OUTPUT_NODE = True - def outer_glow(self, background_image, layer_image, layer_mask, + def outer_glow(self, background_image, layer_image, invert_mask, blend_mode, opacity, grow, blur, glow_color, + layer_mask=None, ): + _canvas = tensor2pil(background_image).convert('RGB') + _layer = tensor2pil(layer_image).convert('RGB') + _mask = tensor2pil(layer_image).convert('RGBA').split()[-1] # 处ç�†mask - if invert_mask: - layer_mask = 1 - layer_mask - _layer = tensor2pil(layer_image) - _mask = mask2image(layer_mask) + if layer_mask is not None: + if invert_mask: + layer_mask = 1 - layer_mask + _mask = mask2image(layer_mask).convert('L') + glow_mask = expand_mask(image2mask(_mask), grow, blur, 0) #扩张,模糊 # å�ˆæˆ�glow glow_color = Image.new("RGB", _layer.size, color=glow_color) alpha = tensor2pil(glow_mask).convert('L') - _canvas = tensor2pil(background_image) _glow = chop_image(tensor2pil(background_image), glow_color, blend_mode, opacity) _canvas.paste(_glow, mask=alpha) # å�ˆæˆ�layer - alpha = tensor2pil(layer_mask).convert('L') - _canvas.paste(_layer, mask=alpha) + _canvas.paste(_layer, mask=_mask) ret_image = _canvas - ret_mask = glow_mask + # ret_mask = glow_mask # return (pil2tensor(ret_image), ret_mask,) return (pil2tensor(ret_image),)