From 5b5cac8d90a96b0b3b6a67d02f902aece8922cb0 Mon Sep 17 00:00:00 2001
From: ussoewwin <136552381+ussoewwin@users.noreply.github.com>
Date: Tue, 19 May 2026 03:29:31 +0900
Subject: [PATCH] docs: replace README language switcher SVGs with PNG assets
---
README.md | 5 +-
README.zh.md | 5 +-
assets/lang-en-active.png | Bin 0 -> 681 bytes
assets/lang-en-active.svg | 10 ---
assets/lang-en-inactive.png | Bin 0 -> 617 bytes
assets/lang-en-inactive.svg | 4 -
assets/lang-switch-en.png | Bin 0 -> 1751 bytes
assets/lang-switch-zh.png | Bin 0 -> 1674 bytes
assets/lang-zh-active.png | Bin 0 -> 1167 bytes
assets/lang-zh-active.svg | 10 ---
assets/lang-zh-inactive.png | Bin 0 -> 1164 bytes
assets/lang-zh-inactive.svg | 4 -
scripts/generate_lang_buttons.py | 141 +++++++++++++++++++++++++++++++
13 files changed, 145 insertions(+), 34 deletions(-)
create mode 100644 assets/lang-en-active.png
delete mode 100644 assets/lang-en-active.svg
create mode 100644 assets/lang-en-inactive.png
delete mode 100644 assets/lang-en-inactive.svg
create mode 100644 assets/lang-switch-en.png
create mode 100644 assets/lang-switch-zh.png
create mode 100644 assets/lang-zh-active.png
delete mode 100644 assets/lang-zh-active.svg
create mode 100644 assets/lang-zh-inactive.png
delete mode 100644 assets/lang-zh-inactive.svg
create mode 100644 scripts/generate_lang_buttons.py
diff --git a/README.md b/README.md
index a44de05..920c5a6 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,8 @@
# ComfyUI-Nunchaku QwenImage&ZImageTurboLoraStack
-
-
-
+ 
A ComfyUI custom node for loading and applying LoRA (Low-Rank Adaptation) to Nunchaku Qwen Image and Z-ImageTurbo models. ComfyUI Nodes 2.0 compatible. **Requires Nunchaku 1.2.0+ and ComfyUI-Nunchaku 1.2.0+ for v4 functionality.**
diff --git a/README.zh.md b/README.zh.md
index 48294a3..c7d2c31 100644
--- a/README.zh.md
+++ b/README.zh.md
@@ -1,9 +1,8 @@
# ComfyUI-Nunchaku QwenImage&ZImageTurboLoraStack
-
-
-
+ 
用于 Nunchaku Qwen Image 和 Z-ImageTurbo 模型的 ComfyUI 自定义节点,支持加载和应用 LoRA(低秩适配)。兼容 ComfyUI Nodes 2.0。**v4 功能需要 Nunchaku 1.2.0+ 和 ComfyUI-Nunchaku 1.2.0+。**
diff --git a/assets/lang-en-active.png b/assets/lang-en-active.png
new file mode 100644
index 0000000000000000000000000000000000000000..effc1a6d62ea491683dc053e2c1a529340d0cf48
GIT binary patch
literal 681
zcmV;a0#^NrP)i6#
zp>i1i(r9EfX-U^<-t8I4$M^!(ixHs#rdKpb6i~D(9{$
z?M$ipuIt(aug2#~h=W^CQ*^YgWy88^>isL|+SkaXhf|U`yOYZ+`tMH`%Lm)*+1%_C
zaXKuX;}c&Pj;9xYv;lpc%~W{|WT>?HsuJKz>?7@){M6NW+1Rj(BfHk4EK3q+cRqj1
zF%bJuET8CT!0+?wEiN1k7;cdF==Cfw$L5QByB)1-^iSN)Q?;&0UjKtBzGsze2kfvN
z0Ek2rWwoD9XBd1kL-+nhXRIp2!GPhG)ZKZWV*JyBbG8F+nd|b(;@rJSl(L-jMyj1p
z3fxZNbfDyRz)eG@
-
-
-
-
-
-
-
- EN
-
diff --git a/assets/lang-en-inactive.png b/assets/lang-en-inactive.png
new file mode 100644
index 0000000000000000000000000000000000000000..2b01f2e5176b62815b1b360c152394d958329889
GIT binary patch
literal 617
zcmV-v0+#)WP)F|9LGQNTBpEnd5Lm~*fKZpR9lNTu`CEeFxFyeqrgK!1$jvD-laoy@(@vwBv?|0
z5K$~em;PBTwgicl8bLy8y5wGVJ2jVMQncw&Q-p;-SA;kZ~`I||(
z{CHWn&JuAyWkuJo)m^J1t5&)IM3yT}!u&-UE%5TQ2?5g365pbsyM&!VRDKG*++^>8yOlN;p^(>QmI}nz&&KSdy^uda+da(7-hklBV
zeTP267MX$j=0x%WaCl$Q>A$Gdzb*t_oDM$<@elX`$i}~QT&&*p00000NkvXXu0mjf
D>N`4G
literal 0
HcmV?d00001
diff --git a/assets/lang-en-inactive.svg b/assets/lang-en-inactive.svg
deleted file mode 100644
index 7925383..0000000
--- a/assets/lang-en-inactive.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/assets/lang-switch-en.png b/assets/lang-switch-en.png
new file mode 100644
index 0000000000000000000000000000000000000000..d7798eedcb8d76ac245ec8083c89ae9b6385c8d7
GIT binary patch
literal 1751
zcmV;|1}OQ7P)m(UL++TkW)HS{h~hrmZJW*&Y
zK@gfFN_`p?ZQWs)t`h`^jto~CMR0bzJyN>2>9JN;7ytLOlh#VqMuDbrXcf6P;K%L2x1ewQ{Oh
zH$iaS)KV;*Ah-|_oFKT+ms4fAmLRy!mlF#o2rk4!xhDB34dlN=&AUiMT8bfa+7#
z?Al$T)rEELgh4fM_O_);N=o-?<)FX-e2qo`{QX<&KT25>K+%ct%)sLFT(cZVcXE9(
zkP4it?FSkd{?Gr*fEhC6>rdM@CcM49wX)4-W8a@;S~)l<5Jfq&Rjk5d;qc*dhkNvk
zHPbKF41nEkXX-zQSrtPkEs@y{z1Ecl6Bh
zVO$wwI&C6z4~}~J!`-9wJfO2)?A78#+%L|o2`)P)pRuDyVKn+^^?&W(&*tKvwQ^#@
zAW3{TBzL~?D}_6cUr-w#FO~G`LwR8S4lzUSHa+Ryjez#;DEn(am6erzzj8IBM<#3a
zD>8n-ZntZ`TTHK>NFJ_LTsbt!A#HHrz(D|Zmz0vV
zK3l6BHDb7fk0^p`f`_$a^%k4m%b>GQQQd3
zd1pTL&BL7wgTX-R*fGq0b1neef7{99&&=d-`4IrTyjn3n?FM9Nmky{tWnXlVn|}VR<02nz=X6L2@Gg2g44?z-E+4eV|niBdB3W_jFe6oR7FNH
z4WEY#2@cZ!f&v2^>Vty<9qLV{3-hUa^*B2_rK&1cH+eT_i-}SK%wD#aLEZf^`Fao$
zd=cZ4+GDfJzFTyhhpXYli3+~@W(BL)W^s04%*F>xKj!COw~?AM27f<45u6@4a-y2o
zmX-2MT4w<67#2*??&G48|H-r|_tm@YzgLyihUMf*)~wB9MMfqS6&CGtqtS&Bx~=Zca_%
z;Ro-hZJX1pgDws2$g@w(;EExG9rAA$i-nBLRXp+R3*_c+LJz0wG^?}#K-|>)I<^1f
zpp|*w?PJolAu_skNdLaErWNmmVCUac5+!}Sb~AIO)>
zmQz@?MXMW{G?=(PG5Yl3q9enVqOCjZx4m25>>ujVHDz37Hqj--M@BgMTdZ*Vgfw2B
zJqL5|Xoe)l*xS8Vz4xBMaVnygtLysqc+Hb*9Re5vmY002ovPDHLkV1jzMXy^a{
literal 0
HcmV?d00001
diff --git a/assets/lang-switch-zh.png b/assets/lang-switch-zh.png
new file mode 100644
index 0000000000000000000000000000000000000000..82a456cd997a9a835ccaeac1be2fc9ea88c99320
GIT binary patch
literal 1674
zcmV;526g#~P)J
zrfStFYT_db)zm7YR#CLzBS4IAd5A(mj}zs@gZ=>=hrofzaSQxD$tF9@&K^5E-~G+}
zezQ9u2!bF8%@I|73SCOQRw7j=2;k@It+I;X%0=eY=@qGE8`8=_Tjg&KTDx9SGYYU?
zDphK2$Jo_XY$7y4uuMrwiEnMfvlF2SLgNWfEn*V{>k6+{!HL)e!8%kcI1!s5SjWn#
z#pN#uHnMQil@tW)S~;~;halLqV$=|gwm0Dq>1Pm<>TVq^gYW@!!3)hvA-Fpv4V0G`jB<6zlV?q@g-xRs@U2I8yv
z-LX`7D~-TpAXh0uYf%>NR$4l-aVH2K94KEyQL?Xf3Wwxi|U%Z})u*H&@qYcWrgK(blBP$}e&5Q#wC4ZE0kr{#0Ux
zd28ds>$`t3rBg>tPbzs*WJbYZ$(oKNlbG*Pg44!C+w9j$O=|HA8Gr
z6XRiGGEXw^q3!62+Chu^xZz}P-eb!5m@vX5HbdGS^5c_`z_+a~P_0I5Zx6tQOUWdj
zzbGx3Cii{|xqA;)2rMiF?aS=|aP;Yd>+nIQyqvB3prk|uXTx`q7#194N=NP7&EvvC
zX~a#8`v;HlB=a5sDy=;o7tTb}+KG+}XPT^A!NtqyjwK*rfrcKHSL3mq|M_S5_Uuuu
z;6jEDA>mvS**Q5p(COH-FNR4I!lV^j0k5TVEav+j*igR*=Tjqh*GA#BY#snky?p4l
zemV9YrDO8qLIYWAHp^T}MLbpPG=xtYZ%W4cd6c-muD{f$lvU4%q%B{u!9QSucsBGyrqolE{d=jgm-Hujz#CV_fR{|JwXqqu+Y7`nqJDZH71QdZfi
zG=@vd$Z8QcGyLQ6Xti2t)e5EU;CJ!f7=e3eNF}iuA3h>0atk--EvG2EbmrFMtGBo|
zeGz&44p)l5X`CJL2n(Ux@88kpeSe!?PjTco%`Yqf@W;ByI+geEaA)+$;q2NQEv;LD
zJUDuqmje6a641MRIv07-vHZ6q2J$6$vI2_oTKB5CQF(!x>R%#zGi8|bof0s2!(&X(#4c6rO>cK<9WgY<=#t>1wRC#rZ`(|Vym--lSLZ^p>AGCK@b$g|AVSZ
U{i)S_@c;k-07*qoM6N<$g0gigssI20
literal 0
HcmV?d00001
diff --git a/assets/lang-zh-active.png b/assets/lang-zh-active.png
new file mode 100644
index 0000000000000000000000000000000000000000..f09369bf3ba520a4f66e6266260efc323304aab1
GIT binary patch
literal 1167
zcmV;A1aSL_P)jPpSi#@KsL|}>=Z+#GPDp_3)~O90L04qWG}3I<$?g`*HK_JupJ9n
z#84>@Z3MR7#{TaHK9N)c9G+=!lOwqOz_Lm1+Y+U%7T6?$6Xog}a3-*=0hUN3Yrr$X
zG4p{3CHCKdJ+R#;2XB)*I4dwDvDLtR61yFcF1v^aQpWXB9r%pR=O+MT!2TF$nBaTY
zN}@{-umR|o3os>sD+6kxqyvTH(t+oI_oMXZ1%3tA1ngB2z&$J3K0OoAq5)%~H79L(
zug)l`^gVB4c*I{v?JO$u$vMbD-tu?IF=wjgR61~@
z`8*@t*ZkwAPD@h3>acdxy1XDXSLam*8(KsHjy*(Et6>5U4^6+Pjhg&}XHSxO#c8
zt?!#7;PVM^a?wC_ebDPvS`CY~7o(1gWzqKHptlX3`wM%0lSl`qqO{UCqPClV-ZwR;
z8}-mrQAyg)E&g&zb`}|5?m}Zq^v@wq7uLN85VcAf%F%QVTUBk)9)kvO^~0}lU9pM;
ze5!Ky_TwFPO0u{Zbc^o}ny!Dk!?L&-gC0$?aq@vm(^-u9E5g0e;~_?`6P1%Y%Dz9V
zjG7L#zg`kC9f&4%yn%%q3T}c1pi-+z-MkUQ!)AIaDjBue1-QxR^0wVmKGt5>h`p{c
z@|+N>$C$qY)4JzT$A#|RcpO6v{8UF$!75Z*jsH)O`#AASbLcx%g{`V4-17yv>5(oi
zl|;*O7Fcpo8}wmq!{;y3RrWdV-hKvu`-8x?C3%+
zPxZ{|;AFwmPmsC4jHDMWVbDA`hOw4^O~;m9xO@E-t^Y1vrmbiPwj;;F@;9|XkEzf?
z#ux9A@Z{1NubRw>sPcO4X&jAbLqFU#!oT1B!ljqD`lHHm3AWei!usjAv=_gHqw!2w
zo9&0=*iZZ}hRW%xlyrZvkMup;aGYwv_G1mB*9UKTn6smc&bL2eenuL`H7n618|kSy
zB#RoQEQ`!Sk+tObL6ul6q%cY6HUUmS&?b65T!2#`v^kN-DH@ph;M`5Xl{lA8=G7VE
hJtrvhJtsm6)&KLGbdn&xz4!nC002ovPDHLkV1nG|K%)Qv
literal 0
HcmV?d00001
diff --git a/assets/lang-zh-active.svg b/assets/lang-zh-active.svg
deleted file mode 100644
index 4c102e8..0000000
--- a/assets/lang-zh-active.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-
diff --git a/assets/lang-zh-inactive.png b/assets/lang-zh-inactive.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ddc6b56c07aebf99037ea75ff2d2ceac362abd4
GIT binary patch
literal 1164
zcmV;71atd|P)o2+2q(IXHa5w0v6`GNGd0tnYKEDp
ziNT~~%BIOQCT4adF4A%pk$|u$OF%;t1ypv~UEA$PAx@!OJL-fug`P5nIE5m_DRizA;uJd9
z32_R=Ln&YM^5szqcD^jPi{E<}PfySPwa@mBF522V=o)Hk(Yu~>vSC6J^|K&@5-V6j+eX>AjyN_W6eS;o#X9U*Y1VO8`7@e-_bEk>ieQY-nQ7-p~HN08puT>A3>@
z{CvfTn=ZLI8_~wcPM8k7zUu|2bfCGljpE%OPq;rxl89NpjQYlA0FE3zc3p9;ZSC@M
zbktpLDQ(VORi-3q<>jW9ql}K4oZ^3+J4fda$K|#@Jx!zo?m%=@B!P==0l;dta;U1t
zDPCdt7Kg(j&us~DF+!X>AW0H;ug!Ey7X}B<18}mhA7ew49NTd3dZ#&5h;uP|U8+3l
zY&IJurDd2*W=i(#l}B6Toe?A_YDGFQ6N*0EJ>xuXGSq4{xtp>ne7_igpHKYCt8cu;
z(C`QVUS9KfByTg~mX{k68xzfHy-sdll?ITX_YgsWi$ntM$~Wt%JcDtQVKK-2IKlPBCla0ThpAa`4c0Tj;%yYDV-6gpm
z=CLtq>x@(wDlwVN@_LQNhs^Xe4pr4+v)KS>X>FsktDCI#>sX^t$J^UWh`Z4YoHGC7f!)?<9%*#*EnPfyllrjvEgIy4%eaoc-&&Ew(C50arv<*Tp1
zp}nI^j;+niaH+I8b*hvki6`>&c)PF&ZG0@N^*a1~r@m<%x;TV_r?%18f10YA!(12|
zCO0P=cPhOS^>GSezMn=C&zzvlN>w3l7F4GSaSAOd_7L5p%o=bZPN8pI@aQ?wD|!s&
ez2`)rQ2qiGr=AZKx*DGV0000
-
- -‡
-
diff --git a/scripts/generate_lang_buttons.py b/scripts/generate_lang_buttons.py
new file mode 100644
index 0000000..3a6bee1
--- /dev/null
+++ b/scripts/generate_lang_buttons.py
@@ -0,0 +1,141 @@
+"""Generate language switcher PNG assets (GitHub-safe, no SVG CJK text)."""
+from __future__ import annotations
+
+from pathlib import Path
+
+from PIL import Image, ImageDraw, ImageFont
+
+ROOT = Path(__file__).resolve().parents[1]
+OUT = ROOT / "assets"
+
+W, H = 220, 44
+SEG_W = W // 2
+R = 12
+PAD = 3
+
+FONT_EN = Path(r"C:\Windows\Fonts\segoeuib.ttf")
+FONT_ZH = Path(r"C:\Windows\Fonts\msyhbd.ttc")
+FALLBACK = Path(r"C:\Windows\Fonts\arialbd.ttf")
+
+
+def _font(path: Path, size: int) -> ImageFont.FreeTypeFont:
+ if path.exists():
+ return ImageFont.truetype(str(path), size)
+ return ImageFont.truetype(str(FALLBACK), size)
+
+
+def _rounded_rect(
+ draw: ImageDraw.ImageDraw,
+ xy: tuple[int, int, int, int],
+ radius: int,
+ fill: tuple[int, ...],
+ corners: tuple[bool, bool, bool, bool] = (True, True, True, True),
+) -> None:
+ x0, y0, x1, y1 = xy
+ if x1 <= x0 or y1 <= y0:
+ return
+ tl, tr, br, bl = corners
+ r = min(radius, (x1 - x0) // 2, (y1 - y0) // 2)
+ if r < 1:
+ draw.rectangle(xy, fill=fill)
+ return
+ if x1 - r > x0 + r:
+ draw.rectangle([x0 + r, y0, x1 - r, y1], fill=fill)
+ if y1 - r > y0 + r:
+ draw.rectangle([x0, y0 + r, x1, y1 - r], fill=fill)
+ if tl:
+ draw.pieslice([x0, y0, x0 + 2 * r, y0 + 2 * r], 180, 270, fill=fill)
+ else:
+ draw.rectangle([x0, y0, x0 + r, y0 + r], fill=fill)
+ if tr:
+ draw.pieslice([x1 - 2 * r, y0, x1, y0 + 2 * r], 270, 360, fill=fill)
+ else:
+ draw.rectangle([x1 - r, y0, x1, y0 + r], fill=fill)
+ if br:
+ draw.pieslice([x1 - 2 * r, y1 - 2 * r, x1, y1], 0, 90, fill=fill)
+ else:
+ draw.rectangle([x1 - r, y1 - r, x1, y1], fill=fill)
+ if bl:
+ draw.pieslice([x0, y1 - 2 * r, x0 + 2 * r, y1], 90, 180, fill=fill)
+ else:
+ draw.rectangle([x0, y1 - r, x0 + r, y1], fill=fill)
+
+
+def _draw_segment(
+ img: Image.Image,
+ index: int,
+ label: str,
+ active: bool,
+ palette: str,
+ font: ImageFont.FreeTypeFont,
+) -> None:
+ draw = ImageDraw.Draw(img)
+ x0 = index * SEG_W
+ x1 = x0 + SEG_W
+ box = (x0 + PAD, PAD, x1 - PAD, H - PAD)
+ corners = (index == 0, index == 1, index == 1, index == 0)
+
+ if active:
+ fill = (52, 112, 204, 255) if palette == "en" else (212, 68, 94, 255)
+ _rounded_rect(draw, box, R, fill, corners)
+ gloss_h = max((box[3] - box[1]) // 2, 6)
+ _rounded_rect(
+ draw,
+ (box[0], box[1], box[2], box[1] + gloss_h),
+ R,
+ (255, 255, 255, 42),
+ corners,
+ )
+ text_color = (255, 255, 255, 255)
+ else:
+ _rounded_rect(draw, box, R, (240, 242, 245, 255), corners)
+ text_color = (82, 90, 99, 255)
+
+ bbox = draw.textbbox((0, 0), label, font=font)
+ tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
+ tx = x0 + (SEG_W - tw) // 2
+ ty = (H - th) // 2 - 1
+ draw.text((tx, ty), label, font=font, fill=text_color)
+
+
+def _make_switcher(en_active: bool) -> Image.Image:
+ img = Image.new("RGBA", (W, H), (0, 0, 0, 0))
+ track = Image.new("RGBA", (W, H), (0, 0, 0, 0))
+ td = ImageDraw.Draw(track)
+ _rounded_rect(td, (2, 2, W - 2, H - 2), R + 2, (210, 214, 220, 255), (True, True, True, True))
+ _rounded_rect(td, (3, 3, W - 3, H - 3), R + 1, (248, 249, 251, 255), (True, True, True, True))
+ img = Image.alpha_composite(img, track)
+
+ font_en = _font(FONT_EN, 22)
+ font_zh = _font(FONT_ZH, 21)
+ _draw_segment(img, 0, "EN", en_active, "en", font_en)
+ _draw_segment(img, 1, "中文", not en_active, "zh", font_zh)
+ return img
+
+
+def _split_halves(full: Image.Image) -> tuple[Image.Image, Image.Image]:
+ return full.crop((0, 0, SEG_W, H)), full.crop((SEG_W, 0, W, H))
+
+
+def main() -> None:
+ OUT.mkdir(parents=True, exist_ok=True)
+
+ en_view = _make_switcher(en_active=True)
+ zh_view = _make_switcher(en_active=False)
+
+ en_l, en_r = _split_halves(en_view)
+ zh_l, zh_r = _split_halves(zh_view)
+
+ en_l.save(OUT / "lang-en-active.png", optimize=True)
+ en_r.save(OUT / "lang-zh-inactive.png", optimize=True)
+ zh_l.save(OUT / "lang-en-inactive.png", optimize=True)
+ zh_r.save(OUT / "lang-zh-active.png", optimize=True)
+
+ en_view.save(OUT / "lang-switch-en.png", optimize=True)
+ zh_view.save(OUT / "lang-switch-zh.png", optimize=True)
+
+ print("Wrote PNG assets to", OUT)
+
+
+if __name__ == "__main__":
+ main()