Spaces:
Paused
Paused
modified: app.py
Browse filesmodified: modutils.py
new file: translate_helper.py
new file: translate_ui.py
new file: translations.py
- app.py +25 -10
- modutils.py +0 -0
- translate_helper.py +74 -0
- translate_ui.py +360 -0
- translations.py +395 -0
app.py
CHANGED
@@ -53,6 +53,14 @@ from diffusers import FluxPipeline
|
|
53 |
# import urllib.parse
|
54 |
import subprocess
|
55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
subprocess.run("rm -rf /data-nvme/zerogpu-offload/*", env={}, shell=True)
|
57 |
|
58 |
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
@@ -158,12 +166,12 @@ from tagger.tagger import (predict_tags_wd, convert_danbooru_to_e621_prompt,
|
|
158 |
compose_prompt_to_copy, translate_prompt, select_random_character)
|
159 |
def description_ui():
|
160 |
gr.Markdown(
|
161 |
-
"""
|
162 |
## Danbooru Tags Transformer V2 Demo with WD Tagger
|
163 |
(Image =>) Prompt => Upsampled longer prompt
|
164 |
- Mod of p1atdev's [Danbooru Tags Transformer V2 Demo](https://huggingface.co/spaces/p1atdev/danbooru-tags-transformer-v2) and [WD Tagger with 🤗 transformers](https://huggingface.co/spaces/p1atdev/wd-tagger-transformers).
|
165 |
- Models: p1atdev's [wd-swinv2-tagger-v3-hf](https://huggingface.co/p1atdev/wd-swinv2-tagger-v3-hf), [dart-v2-moe-sft](https://huggingface.co/p1atdev/dart-v2-moe-sft)
|
166 |
-
"""
|
167 |
)
|
168 |
## END MOD
|
169 |
|
@@ -786,10 +794,11 @@ CSS ="""
|
|
786 |
"""
|
787 |
|
788 |
with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, css=CSS, delete_cache=(60, 3600)) as app:
|
789 |
-
|
790 |
-
gr.Markdown(
|
|
|
791 |
with gr.Column():
|
792 |
-
with gr.Tab("Generation"):
|
793 |
with gr.Row():
|
794 |
with gr.Column(scale=1):
|
795 |
|
@@ -1334,7 +1343,7 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, cs
|
|
1334 |
gr.Markdown(RESOURCES)
|
1335 |
## END MOD
|
1336 |
|
1337 |
-
with gr.Tab("Inpaint mask maker", render=True):
|
1338 |
|
1339 |
def create_mask_now(img, invert):
|
1340 |
import numpy as np
|
@@ -1397,7 +1406,7 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, cs
|
|
1397 |
return img_source, img_result
|
1398 |
btn_send.click(send_img, [img_source, img_result], [image_control, image_mask_gui])
|
1399 |
|
1400 |
-
with gr.Tab("PNG Info"):
|
1401 |
with gr.Row():
|
1402 |
with gr.Column():
|
1403 |
image_metadata = gr.Image(label="Image with metadata", type="pil", sources=["upload"])
|
@@ -1411,7 +1420,7 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, cs
|
|
1411 |
outputs=[result_metadata],
|
1412 |
)
|
1413 |
|
1414 |
-
with gr.Tab("Upscaler"):
|
1415 |
with gr.Row():
|
1416 |
with gr.Column():
|
1417 |
|
@@ -1431,7 +1440,7 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, cs
|
|
1431 |
outputs=[result_up_tab],
|
1432 |
)
|
1433 |
|
1434 |
-
with gr.Tab("Preprocessor", render=True):
|
1435 |
preprocessor_tab()
|
1436 |
|
1437 |
## BEGIN MOD
|
@@ -1686,7 +1695,7 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, cs
|
|
1686 |
).success(save_gallery_images, [result_images, model_name_gui], [result_images, result_images_files], queue=False, show_api=False)\
|
1687 |
.success(save_gallery_history, [result_images, result_images_files, history_gallery, history_files], [history_gallery, history_files], queue=False, show_api=False)
|
1688 |
|
1689 |
-
with gr.Tab("Danbooru Tags Transformer with WD Tagger", render=True):
|
1690 |
with gr.Column(scale=2):
|
1691 |
with gr.Group():
|
1692 |
input_image = gr.Image(label="Input image", type="pil", sources=["upload", "clipboard"], height=256)
|
@@ -1780,5 +1789,11 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, cs
|
|
1780 |
gr.DuplicateButton(value="Duplicate Space for private use (This demo does not work on CPU. Requires GPU Space)")
|
1781 |
|
1782 |
app.queue()
|
|
|
1783 |
app.launch(show_error=True, debug=True) # allowed_paths=["./images/"], show_error=True, debug=True
|
1784 |
## END MOD
|
|
|
|
|
|
|
|
|
|
|
|
53 |
# import urllib.parse
|
54 |
import subprocess
|
55 |
|
56 |
+
# 导入翻译模块
|
57 |
+
import translate_ui
|
58 |
+
from translate_ui import monkey_patch_gradio
|
59 |
+
import translate_helper as th
|
60 |
+
|
61 |
+
# 应用猴子补丁,使所有新创建的Gradio组件自动翻译
|
62 |
+
monkey_patch_gradio()
|
63 |
+
|
64 |
subprocess.run("rm -rf /data-nvme/zerogpu-offload/*", env={}, shell=True)
|
65 |
|
66 |
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
|
|
166 |
compose_prompt_to_copy, translate_prompt, select_random_character)
|
167 |
def description_ui():
|
168 |
gr.Markdown(
|
169 |
+
th.t("""
|
170 |
## Danbooru Tags Transformer V2 Demo with WD Tagger
|
171 |
(Image =>) Prompt => Upsampled longer prompt
|
172 |
- Mod of p1atdev's [Danbooru Tags Transformer V2 Demo](https://huggingface.co/spaces/p1atdev/danbooru-tags-transformer-v2) and [WD Tagger with 🤗 transformers](https://huggingface.co/spaces/p1atdev/wd-tagger-transformers).
|
173 |
- Models: p1atdev's [wd-swinv2-tagger-v3-hf](https://huggingface.co/p1atdev/wd-swinv2-tagger-v3-hf), [dart-v2-moe-sft](https://huggingface.co/p1atdev/dart-v2-moe-sft)
|
174 |
+
""")
|
175 |
)
|
176 |
## END MOD
|
177 |
|
|
|
794 |
"""
|
795 |
|
796 |
with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', elem_id="main", fill_width=True, css=CSS, delete_cache=(60, 3600)) as app:
|
797 |
+
title, description = th.translate_app_title()
|
798 |
+
gr.Markdown(title, elem_classes="title")
|
799 |
+
gr.Markdown(description, elem_classes="info")
|
800 |
with gr.Column():
|
801 |
+
with gr.Tab(th.t("Generation")):
|
802 |
with gr.Row():
|
803 |
with gr.Column(scale=1):
|
804 |
|
|
|
1343 |
gr.Markdown(RESOURCES)
|
1344 |
## END MOD
|
1345 |
|
1346 |
+
with gr.Tab(th.t("Inpaint mask maker"), render=True):
|
1347 |
|
1348 |
def create_mask_now(img, invert):
|
1349 |
import numpy as np
|
|
|
1406 |
return img_source, img_result
|
1407 |
btn_send.click(send_img, [img_source, img_result], [image_control, image_mask_gui])
|
1408 |
|
1409 |
+
with gr.Tab(th.t("PNG Info")):
|
1410 |
with gr.Row():
|
1411 |
with gr.Column():
|
1412 |
image_metadata = gr.Image(label="Image with metadata", type="pil", sources=["upload"])
|
|
|
1420 |
outputs=[result_metadata],
|
1421 |
)
|
1422 |
|
1423 |
+
with gr.Tab(th.t("Upscaler")):
|
1424 |
with gr.Row():
|
1425 |
with gr.Column():
|
1426 |
|
|
|
1440 |
outputs=[result_up_tab],
|
1441 |
)
|
1442 |
|
1443 |
+
with gr.Tab(th.t("Preprocessor"), render=True):
|
1444 |
preprocessor_tab()
|
1445 |
|
1446 |
## BEGIN MOD
|
|
|
1695 |
).success(save_gallery_images, [result_images, model_name_gui], [result_images, result_images_files], queue=False, show_api=False)\
|
1696 |
.success(save_gallery_history, [result_images, result_images_files, history_gallery, history_files], [history_gallery, history_files], queue=False, show_api=False)
|
1697 |
|
1698 |
+
with gr.Tab(th.t("Danbooru Tags Transformer with WD Tagger"), render=True):
|
1699 |
with gr.Column(scale=2):
|
1700 |
with gr.Group():
|
1701 |
input_image = gr.Image(label="Input image", type="pil", sources=["upload", "clipboard"], height=256)
|
|
|
1789 |
gr.DuplicateButton(value="Duplicate Space for private use (This demo does not work on CPU. Requires GPU Space)")
|
1790 |
|
1791 |
app.queue()
|
1792 |
+
th.translate_civitai_constants(app)
|
1793 |
app.launch(show_error=True, debug=True) # allowed_paths=["./images/"], show_error=True, debug=True
|
1794 |
## END MOD
|
1795 |
+
|
1796 |
+
# 自定义一些额外的翻译
|
1797 |
+
def custom_translate(text):
|
1798 |
+
"""自定义翻译函数,以处理特殊情况"""
|
1799 |
+
return translate_ui.translate_text(text)
|
modutils.py
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
translate_helper.py
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
提供简化的函数,用于翻译界面中的文本
|
3 |
+
"""
|
4 |
+
|
5 |
+
from translate_ui import translate_text, translate_special_list
|
6 |
+
import gradio as gr
|
7 |
+
|
8 |
+
def t(text):
|
9 |
+
"""
|
10 |
+
翻译文本的简便方法
|
11 |
+
|
12 |
+
Args:
|
13 |
+
text: 要翻译的文本
|
14 |
+
|
15 |
+
Returns:
|
16 |
+
翻译后的文本
|
17 |
+
"""
|
18 |
+
return translate_text(text)
|
19 |
+
|
20 |
+
def tr(component, text):
|
21 |
+
"""
|
22 |
+
翻译文本并设置到组件的相应属性
|
23 |
+
|
24 |
+
Args:
|
25 |
+
component: 要设置文本的gradio组件
|
26 |
+
text: 要翻译的文本
|
27 |
+
|
28 |
+
Returns:
|
29 |
+
组件自身
|
30 |
+
"""
|
31 |
+
if isinstance(component, (gr.Button, gr.UploadButton)):
|
32 |
+
component.value = translate_text(text)
|
33 |
+
elif isinstance(component, gr.Markdown):
|
34 |
+
component.value = translate_text(text)
|
35 |
+
elif isinstance(component, (gr.Textbox, gr.Number, gr.Slider, gr.Radio, gr.Checkbox,
|
36 |
+
gr.Dropdown, gr.Image, gr.Gallery, gr.CheckboxGroup)):
|
37 |
+
component.label = translate_text(text)
|
38 |
+
elif isinstance(component, (gr.Tab, gr.Accordion)):
|
39 |
+
component.label = translate_text(text)
|
40 |
+
|
41 |
+
return component
|
42 |
+
|
43 |
+
def translate_civitai_constants(app_instance):
|
44 |
+
"""
|
45 |
+
翻译特定于Civitai的常量
|
46 |
+
|
47 |
+
Args:
|
48 |
+
app_instance: 应用实例
|
49 |
+
|
50 |
+
Returns:
|
51 |
+
无
|
52 |
+
"""
|
53 |
+
from modutils import CIVITAI_SORT, CIVITAI_PERIOD
|
54 |
+
|
55 |
+
# 查找包含这些常量的组件并翻译
|
56 |
+
for component in app_instance.blocks.values():
|
57 |
+
if hasattr(component, 'choices'):
|
58 |
+
if component.choices == CIVITAI_SORT:
|
59 |
+
component.choices = translate_special_list(CIVITAI_SORT, "civitai_sort")
|
60 |
+
elif component.choices == CIVITAI_PERIOD:
|
61 |
+
component.choices = translate_special_list(CIVITAI_PERIOD, "civitai_period")
|
62 |
+
|
63 |
+
def translate_app_title(title="# 🧩 图像扩散工坊", description="本应用是对r3gm的DiffuseCraft的修改版本。"):
|
64 |
+
"""
|
65 |
+
返回翻译好的应用标题和描述
|
66 |
+
|
67 |
+
Args:
|
68 |
+
title: 自定义标题(可选)
|
69 |
+
description: 自定义描述(可选)
|
70 |
+
|
71 |
+
Returns:
|
72 |
+
(title, description)元组
|
73 |
+
"""
|
74 |
+
return title, description
|
translate_ui.py
ADDED
@@ -0,0 +1,360 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
这个文件提供了将UI翻译应用到Gradio组件的功能
|
3 |
+
"""
|
4 |
+
|
5 |
+
import gradio as gr
|
6 |
+
from typing import Dict, Any, List, Tuple, Optional, Union, Callable
|
7 |
+
import json
|
8 |
+
|
9 |
+
# 避免循环导入
|
10 |
+
_ui_translations = None
|
11 |
+
_preserve_terms = None
|
12 |
+
_special_translations = {}
|
13 |
+
|
14 |
+
def _load_translations():
|
15 |
+
"""延迟加载翻译数据以避免循环导入"""
|
16 |
+
global _ui_translations, _preserve_terms, _special_translations
|
17 |
+
|
18 |
+
if _ui_translations is None:
|
19 |
+
from translations import (
|
20 |
+
UI_TRANSLATIONS, PRESERVE_TERMS, CIVITAI_BASEMODEL_CN, INTERFACE_MODES_CN,
|
21 |
+
MODEL_TYPES_CN, GENRE_CN, SPEED_CN, TAG_TYPES_CN, TASK_TYPES_CN,
|
22 |
+
IP_ADAPTER_MODES_CN, RECOM_PROMPT_TYPES_CN, RATING_CN, ASPECT_RATIO_CN,
|
23 |
+
LENGTH_CN, IDENTITY_CN
|
24 |
+
)
|
25 |
+
|
26 |
+
_ui_translations = UI_TRANSLATIONS
|
27 |
+
_preserve_terms = PRESERVE_TERMS
|
28 |
+
_special_translations = {
|
29 |
+
"interface_modes": INTERFACE_MODES_CN,
|
30 |
+
"model_types": MODEL_TYPES_CN,
|
31 |
+
"genre": GENRE_CN,
|
32 |
+
"speed": SPEED_CN,
|
33 |
+
"tag_types": TAG_TYPES_CN,
|
34 |
+
"task_types": TASK_TYPES_CN,
|
35 |
+
"ip_adapter_modes": IP_ADAPTER_MODES_CN,
|
36 |
+
"recom_prompt_types": RECOM_PROMPT_TYPES_CN,
|
37 |
+
"rating": RATING_CN,
|
38 |
+
"aspect_ratio": ASPECT_RATIO_CN,
|
39 |
+
"length": LENGTH_CN,
|
40 |
+
"identity": IDENTITY_CN,
|
41 |
+
"civitai_basemodel": CIVITAI_BASEMODEL_CN,
|
42 |
+
}
|
43 |
+
|
44 |
+
def translate_text(text: str) -> str:
|
45 |
+
"""翻译文本,保留特定术语"""
|
46 |
+
if not text or not isinstance(text, str):
|
47 |
+
return text
|
48 |
+
|
49 |
+
# 确保翻译数据已加载
|
50 |
+
if _ui_translations is None:
|
51 |
+
_load_translations()
|
52 |
+
|
53 |
+
# 直接翻译
|
54 |
+
if text in _ui_translations:
|
55 |
+
return _ui_translations[text]
|
56 |
+
|
57 |
+
# 对于包含保留术语的文本,确保术语不被翻译
|
58 |
+
result = text
|
59 |
+
for term in _preserve_terms:
|
60 |
+
# 避免替换部分单词,确保是完整单词或由空格/标点分隔
|
61 |
+
if term in result and (
|
62 |
+
term == result or
|
63 |
+
result.startswith(f"{term} ") or
|
64 |
+
result.endswith(f" {term}") or
|
65 |
+
f" {term} " in result or
|
66 |
+
result.startswith(f"{term},") or
|
67 |
+
result.endswith(f", {term}") or
|
68 |
+
f", {term}," in result
|
69 |
+
):
|
70 |
+
# 保留这个术语
|
71 |
+
pass
|
72 |
+
|
73 |
+
return result
|
74 |
+
|
75 |
+
def translate_dropdown_choices(choices: List) -> List:
|
76 |
+
"""翻译下拉菜单选项"""
|
77 |
+
if not choices:
|
78 |
+
return choices
|
79 |
+
|
80 |
+
if isinstance(choices[0], tuple):
|
81 |
+
# 如果是元组列表 [(label, value), ...]
|
82 |
+
return [(translate_text(label), value) for label, value in choices]
|
83 |
+
else:
|
84 |
+
# 如果是简单列表 [value1, value2, ...]
|
85 |
+
return [translate_text(choice) for choice in choices]
|
86 |
+
|
87 |
+
def translate_dict_choices(choices: Dict) -> Dict:
|
88 |
+
"""翻译字典选项的键"""
|
89 |
+
if not choices:
|
90 |
+
return choices
|
91 |
+
|
92 |
+
return {translate_text(k): v for k, v in choices.items()}
|
93 |
+
|
94 |
+
def apply_translation_to_component(component: Any) -> Any:
|
95 |
+
"""将翻译应用到单个Gradio组件"""
|
96 |
+
if not component:
|
97 |
+
return component
|
98 |
+
|
99 |
+
# 确保翻译数据已加载
|
100 |
+
if _ui_translations is None:
|
101 |
+
_load_translations()
|
102 |
+
|
103 |
+
# 不同类型组件的翻译逻辑
|
104 |
+
if isinstance(component, (gr.Button, gr.UploadButton)):
|
105 |
+
if hasattr(component, 'value') and component.value:
|
106 |
+
component.value = translate_text(component.value)
|
107 |
+
|
108 |
+
elif isinstance(component, (gr.Textbox, gr.Number, gr.Slider, gr.Radio, gr.Checkbox,
|
109 |
+
gr.Dropdown, gr.Image, gr.Gallery, gr.CheckboxGroup)):
|
110 |
+
if hasattr(component, 'label') and component.label:
|
111 |
+
component.label = translate_text(component.label)
|
112 |
+
|
113 |
+
if hasattr(component, 'info') and component.info:
|
114 |
+
component.info = translate_text(component.info)
|
115 |
+
|
116 |
+
# 对于有choices属性的组件
|
117 |
+
if hasattr(component, 'choices') and component.choices:
|
118 |
+
# 处理不同类型的选项
|
119 |
+
if isinstance(component, gr.Radio):
|
120 |
+
# 特殊类型翻译
|
121 |
+
if set(component.choices) == set(["Simple", "Standard", "Fast", "LoRA"]):
|
122 |
+
component.choices = [_special_translations["interface_modes"].get(c, c) for c in component.choices]
|
123 |
+
elif set(component.choices) == set(["None", "Auto", "Animagine", "Pony"]):
|
124 |
+
component.choices = [_special_translations["model_types"].get(c, c) for c in component.choices]
|
125 |
+
elif set(component.choices) == set(["Anime", "Photo"]):
|
126 |
+
component.choices = [_special_translations["genre"].get(c, c) for c in component.choices]
|
127 |
+
elif set(component.choices) == set(["Fast", "Standard", "Heavy"]):
|
128 |
+
component.choices = [_special_translations["speed"].get(c, c) for c in component.choices]
|
129 |
+
elif set(component.choices) & set(["danbooru", "e621", "body", "dress", "all"]):
|
130 |
+
component.choices = [_special_translations["tag_types"].get(c, c) for c in component.choices]
|
131 |
+
elif set(component.choices) & set(["original", "style"]):
|
132 |
+
component.choices = [_special_translations["ip_adapter_modes"].get(c, c) for c in component.choices]
|
133 |
+
elif set(component.choices) & set(["None", "Auto", "Animagine", "Pony"]):
|
134 |
+
component.choices = [_special_translations["recom_prompt_types"].get(c, c) for c in component.choices]
|
135 |
+
else:
|
136 |
+
component.choices = [translate_text(c) for c in component.choices]
|
137 |
+
elif isinstance(component, gr.CheckboxGroup):
|
138 |
+
if any(c in _special_translations["civitai_basemodel"] for c in component.choices):
|
139 |
+
component.choices = [_special_translations["civitai_basemodel"].get(c, c) for c in component.choices]
|
140 |
+
else:
|
141 |
+
component.choices = [translate_text(c) for c in component.choices]
|
142 |
+
else:
|
143 |
+
component.choices = translate_dropdown_choices(component.choices)
|
144 |
+
|
145 |
+
# 对于有值的组件
|
146 |
+
if hasattr(component, 'placeholder') and component.placeholder:
|
147 |
+
component.placeholder = translate_text(component.placeholder)
|
148 |
+
|
149 |
+
elif isinstance(component, gr.Markdown):
|
150 |
+
if hasattr(component, 'value') and component.value:
|
151 |
+
component.value = translate_text(component.value)
|
152 |
+
|
153 |
+
return component
|
154 |
+
|
155 |
+
def apply_translation_to_ui(block: gr.Blocks) -> None:
|
156 |
+
"""递归地将翻译应用到整个UI"""
|
157 |
+
if not block:
|
158 |
+
return
|
159 |
+
|
160 |
+
# 如果是Blocks实例处理其子项
|
161 |
+
if isinstance(block, gr.Blocks):
|
162 |
+
for child in block.children:
|
163 |
+
apply_translation_to_ui(child)
|
164 |
+
|
165 |
+
# 如果是Row, Column, Group等容器
|
166 |
+
elif hasattr(block, 'children'):
|
167 |
+
for child in block.children:
|
168 |
+
apply_translation_to_ui(child)
|
169 |
+
|
170 |
+
# 如果是Accordion、Tab等特殊容器
|
171 |
+
elif isinstance(block, (gr.Accordion, gr.Tab, gr.TabItem)):
|
172 |
+
# 翻译标签
|
173 |
+
if hasattr(block, 'label') and block.label:
|
174 |
+
block.label = translate_text(block.label)
|
175 |
+
|
176 |
+
# 处理子项
|
177 |
+
if hasattr(block, 'children'):
|
178 |
+
for child in block.children:
|
179 |
+
apply_translation_to_ui(child)
|
180 |
+
|
181 |
+
# 如果是具体的组件
|
182 |
+
else:
|
183 |
+
apply_translation_to_component(block)
|
184 |
+
|
185 |
+
def translate_task_choices(task_choices: List[str]) -> List[str]:
|
186 |
+
"""翻译任务选项"""
|
187 |
+
return [TASK_TYPES_CN.get(task, task) for task in task_choices]
|
188 |
+
|
189 |
+
def create_translating_app(original_app: gr.Blocks) -> gr.Blocks:
|
190 |
+
"""创建应用翻译后的版本"""
|
191 |
+
# 复制原始app
|
192 |
+
app_copy = original_app
|
193 |
+
|
194 |
+
# 应用翻译
|
195 |
+
apply_translation_to_ui(app_copy)
|
196 |
+
|
197 |
+
return app_copy
|
198 |
+
|
199 |
+
def monkey_patch_gradio():
|
200 |
+
"""猴子补丁Gradio组件以自动翻译"""
|
201 |
+
# 确保翻译数据已加载
|
202 |
+
if _ui_translations is None:
|
203 |
+
_load_translations()
|
204 |
+
|
205 |
+
# 保存原始方法
|
206 |
+
original_textbox = gr.Textbox
|
207 |
+
original_button = gr.Button
|
208 |
+
original_checkbox = gr.Checkbox
|
209 |
+
original_radio = gr.Radio
|
210 |
+
original_slider = gr.Slider
|
211 |
+
original_dropdown = gr.Dropdown
|
212 |
+
original_markdown = gr.Markdown
|
213 |
+
original_tab = gr.Tab
|
214 |
+
original_accordion = gr.Accordion
|
215 |
+
|
216 |
+
# 替换方法
|
217 |
+
def patched_textbox(*args, **kwargs):
|
218 |
+
if 'label' in kwargs and kwargs['label']:
|
219 |
+
kwargs['label'] = translate_text(kwargs['label'])
|
220 |
+
if 'placeholder' in kwargs and kwargs['placeholder']:
|
221 |
+
kwargs['placeholder'] = translate_text(kwargs['placeholder'])
|
222 |
+
if 'info' in kwargs and kwargs['info']:
|
223 |
+
kwargs['info'] = translate_text(kwargs['info'])
|
224 |
+
return original_textbox(*args, **kwargs)
|
225 |
+
|
226 |
+
def patched_button(*args, **kwargs):
|
227 |
+
if 'value' in kwargs and kwargs['value']:
|
228 |
+
kwargs['value'] = translate_text(kwargs['value'])
|
229 |
+
return original_button(*args, **kwargs)
|
230 |
+
|
231 |
+
def patched_checkbox(*args, **kwargs):
|
232 |
+
if 'label' in kwargs and kwargs['label']:
|
233 |
+
kwargs['label'] = translate_text(kwargs['label'])
|
234 |
+
if 'info' in kwargs and kwargs['info']:
|
235 |
+
kwargs['info'] = translate_text(kwargs['info'])
|
236 |
+
return original_checkbox(*args, **kwargs)
|
237 |
+
|
238 |
+
def patched_radio(*args, **kwargs):
|
239 |
+
if 'label' in kwargs and kwargs['label']:
|
240 |
+
kwargs['label'] = translate_text(kwargs['label'])
|
241 |
+
if 'info' in kwargs and kwargs['info']:
|
242 |
+
kwargs['info'] = translate_text(kwargs['info'])
|
243 |
+
if 'choices' in kwargs and kwargs['choices']:
|
244 |
+
# 特殊类型翻译
|
245 |
+
if set(kwargs['choices']) == set(["Simple", "Standard", "Fast", "LoRA"]):
|
246 |
+
kwargs['choices'] = [_special_translations["interface_modes"].get(c, c) for c in kwargs['choices']]
|
247 |
+
elif set(kwargs['choices']) == set(["None", "Auto", "Animagine", "Pony"]):
|
248 |
+
kwargs['choices'] = [_special_translations["model_types"].get(c, c) for c in kwargs['choices']]
|
249 |
+
elif set(kwargs['choices']) == set(["Anime", "Photo"]):
|
250 |
+
kwargs['choices'] = [_special_translations["genre"].get(c, c) for c in kwargs['choices']]
|
251 |
+
elif set(kwargs['choices']) == set(["Fast", "Standard", "Heavy"]):
|
252 |
+
kwargs['choices'] = [_special_translations["speed"].get(c, c) for c in kwargs['choices']]
|
253 |
+
elif set(kwargs['choices']) & set(["danbooru", "e621", "body", "dress", "all"]):
|
254 |
+
kwargs['choices'] = [_special_translations["tag_types"].get(c, c) for c in kwargs['choices']]
|
255 |
+
elif set(kwargs['choices']) & set(["original", "style"]):
|
256 |
+
kwargs['choices'] = [_special_translations["ip_adapter_modes"].get(c, c) for c in kwargs['choices']]
|
257 |
+
elif set(kwargs['choices']) & set(["None", "Auto", "Animagine", "Pony"]):
|
258 |
+
kwargs['choices'] = [_special_translations["recom_prompt_types"].get(c, c) for c in kwargs['choices']]
|
259 |
+
else:
|
260 |
+
kwargs['choices'] = [translate_text(c) for c in kwargs['choices']]
|
261 |
+
return original_radio(*args, **kwargs)
|
262 |
+
|
263 |
+
def patched_slider(*args, **kwargs):
|
264 |
+
if 'label' in kwargs and kwargs['label']:
|
265 |
+
kwargs['label'] = translate_text(kwargs['label'])
|
266 |
+
if 'info' in kwargs and kwargs['info']:
|
267 |
+
kwargs['info'] = translate_text(kwargs['info'])
|
268 |
+
return original_slider(*args, **kwargs)
|
269 |
+
|
270 |
+
def patched_dropdown(*args, **kwargs):
|
271 |
+
if 'label' in kwargs and kwargs['label']:
|
272 |
+
kwargs['label'] = translate_text(kwargs['label'])
|
273 |
+
if 'info' in kwargs and kwargs['info']:
|
274 |
+
kwargs['info'] = translate_text(kwargs['info'])
|
275 |
+
if 'choices' in kwargs and kwargs['choices']:
|
276 |
+
# 识别并保留特殊的选择项
|
277 |
+
if isinstance(kwargs['choices'], list) and len(kwargs['choices']) > 0:
|
278 |
+
if isinstance(kwargs['choices'][0], tuple):
|
279 |
+
# 如果是元组列表 [(label, value), ...]
|
280 |
+
kwargs['choices'] = [(translate_text(label), value) for label, value in kwargs['choices']]
|
281 |
+
else:
|
282 |
+
# 如果是简单列表 [value1, value2, ...]
|
283 |
+
kwargs['choices'] = [translate_text(choice) for choice in kwargs['choices']]
|
284 |
+
return original_dropdown(*args, **kwargs)
|
285 |
+
|
286 |
+
def patched_markdown(*args, **kwargs):
|
287 |
+
if args and isinstance(args[0], str):
|
288 |
+
args = list(args)
|
289 |
+
args[0] = translate_text(args[0])
|
290 |
+
args = tuple(args)
|
291 |
+
if 'value' in kwargs and kwargs['value']:
|
292 |
+
kwargs['value'] = translate_text(kwargs['value'])
|
293 |
+
return original_markdown(*args, **kwargs)
|
294 |
+
|
295 |
+
def patched_tab(*args, **kwargs):
|
296 |
+
if 'label' in kwargs and kwargs['label']:
|
297 |
+
kwargs['label'] = translate_text(kwargs['label'])
|
298 |
+
return original_tab(*args, **kwargs)
|
299 |
+
|
300 |
+
def patched_accordion(*args, **kwargs):
|
301 |
+
if 'label' in kwargs and kwargs['label']:
|
302 |
+
kwargs['label'] = translate_text(kwargs['label'])
|
303 |
+
return original_accordion(*args, **kwargs)
|
304 |
+
|
305 |
+
# 应用补丁
|
306 |
+
gr.Textbox = patched_textbox
|
307 |
+
gr.Button = patched_button
|
308 |
+
gr.Checkbox = patched_checkbox
|
309 |
+
gr.Radio = patched_radio
|
310 |
+
gr.Slider = patched_slider
|
311 |
+
gr.Dropdown = patched_dropdown
|
312 |
+
gr.Markdown = patched_markdown
|
313 |
+
gr.Tab = patched_tab
|
314 |
+
gr.Accordion = patched_accordion
|
315 |
+
|
316 |
+
def translate_special_list(choice_list, list_type):
|
317 |
+
"""翻译特殊列表,如Civitai排序、时间段等"""
|
318 |
+
# 确保翻译数据已加载
|
319 |
+
if _ui_translations is None:
|
320 |
+
_load_translations()
|
321 |
+
|
322 |
+
# 处理已知的特殊列表
|
323 |
+
if list_type == "civitai_sort":
|
324 |
+
translations = {
|
325 |
+
"Highest Rated": "最高评分",
|
326 |
+
"Most Downloaded": "最多下载",
|
327 |
+
"Most Liked": "最多点赞",
|
328 |
+
"Most Discussed": "最多讨论",
|
329 |
+
"Most Collected": "最多收藏",
|
330 |
+
"Most Buzz": "最多热度",
|
331 |
+
"Newest": "最新"
|
332 |
+
}
|
333 |
+
return [translations.get(item, item) for item in choice_list]
|
334 |
+
|
335 |
+
elif list_type == "civitai_period":
|
336 |
+
translations = {
|
337 |
+
"AllTime": "所有时间",
|
338 |
+
"Year": "年",
|
339 |
+
"Month": "月",
|
340 |
+
"Week": "周",
|
341 |
+
"Day": "日"
|
342 |
+
}
|
343 |
+
return [translations.get(item, item) for item in choice_list]
|
344 |
+
|
345 |
+
elif list_type == "civitai_basemodel":
|
346 |
+
# 这些通常保持不变
|
347 |
+
return choice_list
|
348 |
+
|
349 |
+
# 默认直接翻译每一项
|
350 |
+
return [translate_text(item) for item in choice_list]
|
351 |
+
|
352 |
+
def get_translated_constants():
|
353 |
+
"""获取预先翻译好的常量"""
|
354 |
+
from modutils import CIVITAI_SORT, CIVITAI_PERIOD, CIVITAI_BASEMODEL
|
355 |
+
|
356 |
+
global _translated_civitai_sort, _translated_civitai_period
|
357 |
+
|
358 |
+
_translated_civitai_sort = translate_special_list(CIVITAI_SORT, "civitai_sort")
|
359 |
+
_translated_civitai_period = translate_special_list(CIVITAI_PERIOD, "civitai_period")
|
360 |
+
# CIVITAI_BASEMODEL通常不需要翻译
|
translations.py
ADDED
@@ -0,0 +1,395 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
这个文件包含DiffuseCraftMod的中文翻译
|
3 |
+
"""
|
4 |
+
|
5 |
+
# UI主要标题和描述
|
6 |
+
UI_TRANSLATIONS = {
|
7 |
+
# 主标题
|
8 |
+
"# 🧩 DiffuseCraft Mod": "# 🧩 图像扩散工坊",
|
9 |
+
"This space is a modification of [r3gm's DiffuseCraft](https://huggingface.co/spaces/r3gm/DiffuseCraft).": "本应用是对[r3gm的DiffuseCraft](https://huggingface.co/spaces/r3gm/DiffuseCraft)的修改版本。",
|
10 |
+
|
11 |
+
# Danbooru Tags Transformer说明
|
12 |
+
"""
|
13 |
+
## Danbooru Tags Transformer V2 Demo with WD Tagger
|
14 |
+
(Image =>) Prompt => Upsampled longer prompt
|
15 |
+
- Mod of p1atdev's [Danbooru Tags Transformer V2 Demo](https://huggingface.co/spaces/p1atdev/danbooru-tags-transformer-v2) and [WD Tagger with 🤗 transformers](https://huggingface.co/spaces/p1atdev/wd-tagger-transformers).
|
16 |
+
- Models: p1atdev's [wd-swinv2-tagger-v3-hf](https://huggingface.co/p1atdev/wd-swinv2-tagger-v3-hf), [dart-v2-moe-sft](https://huggingface.co/p1atdev/dart-v2-moe-sft)
|
17 |
+
""": """
|
18 |
+
## 图像标签生成器
|
19 |
+
(图像 =>) 提示词 => 扩展的更长提示词
|
20 |
+
- 基于p1atdev的[Danbooru标签转换器V2演示](https://huggingface.co/spaces/p1atdev/danbooru-tags-transformer-v2)和[带有🤗 transformers的WD标签生成器](https://huggingface.co/spaces/p1atdev/wd-tagger-transformers)进行修改。
|
21 |
+
- 使用模型: p1atdev的[wd-swinv2-tagger-v3-hf](https://huggingface.co/p1atdev/wd-swinv2-tagger-v3-hf), [dart-v2-moe-sft](https://huggingface.co/p1atdev/dart-v2-moe-sft)
|
22 |
+
""",
|
23 |
+
|
24 |
+
# 标签页
|
25 |
+
"Generation": "图像生成",
|
26 |
+
"Inpaint mask maker": "蒙版制作",
|
27 |
+
"PNG Info": "PNG信息",
|
28 |
+
"Upscaler": "图像放大",
|
29 |
+
"Preprocessor": "预处理器",
|
30 |
+
"Danbooru Tags Transformer with WD Tagger": "图像标签生成器",
|
31 |
+
|
32 |
+
# 常见按钮
|
33 |
+
"GENERATE IMAGE": "生成图像",
|
34 |
+
"GENERATE TAGS FROM IMAGE": "从图像生成标签",
|
35 |
+
"START UPSCALE": "开始放大",
|
36 |
+
"PROCESS IMAGE": "处理图像",
|
37 |
+
"Get and Refresh the LoRA Lists": "获取并刷新LoRA列表",
|
38 |
+
"Search on Civitai": "在Civitai上搜索",
|
39 |
+
"Upload LoRA from your disk (very slow)": "从本地上传LoRA (速度很慢)",
|
40 |
+
"Copy to clipboard": "复制到剪贴板",
|
41 |
+
"Copy to primary prompt": "复制到主提示词",
|
42 |
+
"Copy example to prompt": "复制示例到提示词",
|
43 |
+
"Translate prompt to English": "将提示词翻译为英语",
|
44 |
+
"Translate Prompt 📝": "翻译提示词 📝",
|
45 |
+
"Convert prompt to Pony e621 style": "转换为Pony e621风格",
|
46 |
+
"Clear 🗑️": "清除 🗑️",
|
47 |
+
"Seed 🎲": "随机种子 🎲",
|
48 |
+
"Params ↙️": "参数 ↙️",
|
49 |
+
"Random character 🎲": "随机角色 🎲",
|
50 |
+
"EXTEND PROMPT 🎲": "扩展提示词 🎲",
|
51 |
+
"Create mask": "创建蒙版",
|
52 |
+
"Send to the first tab": "发送到第一个标签页",
|
53 |
+
|
54 |
+
# 手风琴标题
|
55 |
+
"Model and Task": "模型与任务",
|
56 |
+
"Prompt from Image": "从图像生成提示词",
|
57 |
+
"Negative prompt, etc.": "负面提示词等",
|
58 |
+
"LoRA": "LoRA模型",
|
59 |
+
"From URL": "从URL",
|
60 |
+
"From Local": "从本地",
|
61 |
+
"Generation settings": "生成设置",
|
62 |
+
"Hires fix": "高清修复",
|
63 |
+
"Detailfix": "细节修复",
|
64 |
+
"Detailfix A": "细节修复A",
|
65 |
+
"Detailfix B": "细节修复B",
|
66 |
+
"Face restoration": "面部修复",
|
67 |
+
"Textual inversion": "文本反转",
|
68 |
+
"ControlNet / Img2img / Inpaint": "控制网络/图像生成/修复",
|
69 |
+
"IP-Adapter": "IP适配器",
|
70 |
+
"IP-Adapter 1": "IP适配器 1",
|
71 |
+
"IP-Adapter 2": "IP适配器 2",
|
72 |
+
"T2I adapter": "文本到图像适配器",
|
73 |
+
"Styles": "风格",
|
74 |
+
"Other settings": "其他设置",
|
75 |
+
"More settings": "更多设置",
|
76 |
+
"Advanced options": "高级选项",
|
77 |
+
"Select from Gallery": "从画廊中选择",
|
78 |
+
"History": "历史记录",
|
79 |
+
"Examples and help": "示例与帮助",
|
80 |
+
|
81 |
+
# 常见标签和输入框
|
82 |
+
"Quick settings": "快速设置",
|
83 |
+
"Task": "任务",
|
84 |
+
"Model": "模型",
|
85 |
+
"Model Type": "模型类型",
|
86 |
+
"Genre": "类型",
|
87 |
+
"Speed": "速度",
|
88 |
+
"Aspect Ratio": "宽高比",
|
89 |
+
"Quality Tags Presets": "品质标签预设",
|
90 |
+
"Style Preset": "风格预设",
|
91 |
+
"Sampler Quick Settings": "采样器快速设置",
|
92 |
+
"Optimization for SDXL": "SDXL优化",
|
93 |
+
"Input image": "输入图像",
|
94 |
+
"Threshold": "阈值",
|
95 |
+
"Character threshold": "角色阈值",
|
96 |
+
"Convert tags to": "标签转换为",
|
97 |
+
"Insert reccomended prompt": "插入推荐提示词",
|
98 |
+
"Remove tags leaving only the following": "移除标签只保留以下",
|
99 |
+
"Prompt": "提示词",
|
100 |
+
"Negative prompt": "负面提示词",
|
101 |
+
"Insert reccomended positive / negative prompt": "插入推荐正/负面提示词",
|
102 |
+
"Character names": "角色名称",
|
103 |
+
"Series names": "系列名称",
|
104 |
+
"Rating": "评分",
|
105 |
+
"Images": "图像数",
|
106 |
+
"Seed": "种子",
|
107 |
+
"Steps": "步数",
|
108 |
+
"CFG": "CFG值",
|
109 |
+
"CFG rescale:": "CFG重缩放:",
|
110 |
+
"Img Width": "图像宽��",
|
111 |
+
"Img Height": "图像高度",
|
112 |
+
"PAG Scale": "PAG比例",
|
113 |
+
"Layer 2 Clip Skip": "第2层Clip跳过",
|
114 |
+
"FreeU": "FreeU增强",
|
115 |
+
"Sampler": "采样器",
|
116 |
+
"Schedule type": "调度类型",
|
117 |
+
"Discrete Sampling Type": "离散采样类型",
|
118 |
+
"VAE Model": "VAE模型",
|
119 |
+
"Prompt Syntax": "提示词语法",
|
120 |
+
|
121 |
+
# LoRA相关
|
122 |
+
"LoRA1": "LoRA1",
|
123 |
+
"LoRA Scale 1": "LoRA比例 1",
|
124 |
+
"LoRA1 prompts": "LoRA1提示词",
|
125 |
+
"LoRA2": "LoRA2",
|
126 |
+
"LoRA Scale 2": "LoRA比例 2",
|
127 |
+
"LoRA2 prompts": "LoRA2提示词",
|
128 |
+
"LoRA3": "LoRA3",
|
129 |
+
"LoRA Scale 3": "LoRA比例 3",
|
130 |
+
"LoRA3 prompts": "LoRA3提示词",
|
131 |
+
"LoRA4": "LoRA4",
|
132 |
+
"LoRA Scale 4": "LoRA比例 4",
|
133 |
+
"LoRA4 prompts": "LoRA4提示词",
|
134 |
+
"LoRA5": "LoRA5",
|
135 |
+
"LoRA Scale 5": "LoRA比例 5",
|
136 |
+
"LoRA5 prompts": "LoRA5提示词",
|
137 |
+
"LoRA6": "LoRA6",
|
138 |
+
"LoRA Scale 6": "LoRA比例 6",
|
139 |
+
"LoRA6 prompts": "LoRA6提示词",
|
140 |
+
"LoRA7": "LoRA7",
|
141 |
+
"LoRA Scale 7": "LoRA比例 7",
|
142 |
+
"LoRA7 prompts": "LoRA7提示词",
|
143 |
+
"Search LoRA for": "搜索LoRA模型",
|
144 |
+
"Sort": "排序",
|
145 |
+
"Period": "时间段",
|
146 |
+
"Query": "查询",
|
147 |
+
"Tag": "标签",
|
148 |
+
"Username": "用户名",
|
149 |
+
"Search Results": "搜索结果",
|
150 |
+
"LoRA's download URL": "LoRA下载URL",
|
151 |
+
"Transliterate name": "音译名称",
|
152 |
+
"Uploaded LoRA": "已上传的LoRA",
|
153 |
+
|
154 |
+
# 高清修复
|
155 |
+
"Upscaler": "放大器",
|
156 |
+
"Upscale by": "放大倍数",
|
157 |
+
"Upscaler Tile Size": "放大器瓦片大小",
|
158 |
+
"Upscaler Tile Overlap": "放大器瓦片重叠",
|
159 |
+
"Hires Steps": "高清步数",
|
160 |
+
"Hires Denoising Strength": "高清去噪强度",
|
161 |
+
"Hires Sampler": "高清采样器",
|
162 |
+
"Hires Schedule type": "高清调度类型",
|
163 |
+
"Hires CFG": "高清CFG",
|
164 |
+
"Hires Prompt": "高清提示词",
|
165 |
+
"Hires Negative Prompt": "高清负面提示词",
|
166 |
+
|
167 |
+
# 细节修复
|
168 |
+
"Inpaint only": "仅修复",
|
169 |
+
"Verbose": "详细输出",
|
170 |
+
"Adetailer sampler:": "Adetailer采样器:",
|
171 |
+
"Enable Adetailer A": "启用Adetailer A",
|
172 |
+
"Main prompt": "主提示词",
|
173 |
+
"Negative prompt": "负面提示词",
|
174 |
+
"Strength:": "强度:",
|
175 |
+
"Face detector": "面部检测器",
|
176 |
+
"Person detector": "人物检测器",
|
177 |
+
"Hand detector": "手部检测器",
|
178 |
+
"Mask dilation:": "蒙版扩张:",
|
179 |
+
"Mask blur:": "蒙版模糊:",
|
180 |
+
"Mask padding:": "蒙版填充:",
|
181 |
+
"Enable Adetailer B": "启用Adetailer B",
|
182 |
+
|
183 |
+
# 面部修复
|
184 |
+
"Face restoration model": "面部修复模型",
|
185 |
+
"Visibility": "可见度",
|
186 |
+
"Weight": "权重",
|
187 |
+
|
188 |
+
# 文本反转
|
189 |
+
"Active Textual Inversion in prompt": "在提示词中启用文本反转",
|
190 |
+
"Use Textual Invertion in prompt": "在提示词中使用文本反转",
|
191 |
+
|
192 |
+
# ControlNet/图像生成/修复
|
193 |
+
"Image ControlNet/Inpaint/Img2img": "控制网络/修复/图像生成用图",
|
194 |
+
"Image Mask": "蒙版图像",
|
195 |
+
"Strength": "强度",
|
196 |
+
"Image Resolution": "图像分辨率",
|
197 |
+
"ControlNet model": "控制网络模型",
|
198 |
+
"ControlNet Output Scaling in UNet": "UNet中控制网络输出缩放",
|
199 |
+
"ControlNet Start Threshold (%)": "控制网络开始阈值(%)",
|
200 |
+
"ControlNet Stop Threshold (%)": "控制网络停止阈值(%)",
|
201 |
+
"Preprocessor Name": "预处理器名称",
|
202 |
+
"Preprocessor Resolution": "预处理器分辨率",
|
203 |
+
"'CANNY' low threshold": "'CANNY'低阈值",
|
204 |
+
"'CANNY' high threshold": "'CANNY'高阈值",
|
205 |
+
"'MLSD' Hough value threshold": "'MLSD' Hough值阈值",
|
206 |
+
"'MLSD' Hough distance threshold": "'MLSD' Hough距离阈值",
|
207 |
+
"'RECOLOR' gamma correction": "'RECOLOR'伽马校正",
|
208 |
+
"'TILE' blur sigma": "'TILE'模糊sigma",
|
209 |
+
|
210 |
+
# IP适配器
|
211 |
+
"IP Image": "IP图像",
|
212 |
+
"IP Mask": "IP蒙版",
|
213 |
+
"IP Mask (optional)": "IP蒙版(可选)",
|
214 |
+
"Scale": "比例",
|
215 |
+
"Mode": "模式",
|
216 |
+
|
217 |
+
# T2I适配器
|
218 |
+
"T2i Adapter Preprocessor": "T2i适配器预处理器",
|
219 |
+
"Adapter Conditioning Scale": "适配器条件缩放",
|
220 |
+
"Adapter Conditioning Factor (%)": "适配器条件因子(%)",
|
221 |
+
|
222 |
+
# 样式
|
223 |
+
"Style Prompt": "风格提示词",
|
224 |
+
"Style JSON File": "风格JSON文件",
|
225 |
+
"Load styles": "加载风格",
|
226 |
+
|
227 |
+
# 其他设置
|
228 |
+
"Save Generated Images": "保存生成的图像",
|
229 |
+
"Filename pattern": "文件名模式",
|
230 |
+
"Hires Before Adetailer": "Adetailer前高清处理",
|
231 |
+
"Hires After Adetailer": "Adetailer后高清处理",
|
232 |
+
"Generator in CPU": "在CPU中生成",
|
233 |
+
"Loop Generation": "循环生成",
|
234 |
+
"Retain task model in cache": "在缓存中保留任务模型",
|
235 |
+
"Leave Progress Bar": "保留进度条",
|
236 |
+
"Disable Progress Bar": "禁用进度条",
|
237 |
+
"Display Images": "显示图像",
|
238 |
+
"Image Previews": "图像预览",
|
239 |
+
"Image Storage Location": "图像存储位置",
|
240 |
+
"Retain Compel Previous Load": "保留Compel前次加载",
|
241 |
+
"Retain Detailfix Model Previous Load": "保留Detailfix模型前次加载",
|
242 |
+
"Retain Hires Model Previous Load": "保留Hires模型前次加载",
|
243 |
+
"Xformers Memory Efficient Attention": "Xformers内存高效注意力",
|
244 |
+
|
245 |
+
# Civitai相关
|
246 |
+
"Highest Rated": "最高评分",
|
247 |
+
"Most Downloaded": "最多下载",
|
248 |
+
"Most Liked": "最多点赞",
|
249 |
+
"Most Discussed": "最多讨论",
|
250 |
+
"Most Collected": "最多收藏",
|
251 |
+
"Most Buzz": "最多热度",
|
252 |
+
"Newest": "最新",
|
253 |
+
"AllTime": "所有时间",
|
254 |
+
"Year": "年",
|
255 |
+
"Month": "月",
|
256 |
+
"Week": "周",
|
257 |
+
"Day": "日",
|
258 |
+
|
259 |
+
# PNG信息
|
260 |
+
"Image with metadata": "带元数据的图像",
|
261 |
+
"Metadata": "元数据",
|
262 |
+
|
263 |
+
# 图像处理相关
|
264 |
+
"Base image": "基础图像",
|
265 |
+
"Invert mask": "反转蒙版",
|
266 |
+
"Mask image": "蒙版图像",
|
267 |
+
"Generated images": "生成的图像",
|
268 |
+
"Image": "图像",
|
269 |
+
"Result": "结果",
|
270 |
+
"Output tags": "输出标签",
|
271 |
+
"Output tags (Pony e621 style)": "输出标签(Pony e621风格)"
|
272 |
+
}
|
273 |
+
|
274 |
+
# 保留原始英文的术语
|
275 |
+
PRESERVE_TERMS = [
|
276 |
+
"LoRA", "VAE", "SDXL", "ControlNet", "UNet", "FreeU", "CANNY", "MLSD", "RECOLOR", "TILE",
|
277 |
+
"IP-Adapter", "T2I", "PNG", "CPU", "Adetailer", "Hires", "Compel", "Xformers", "Civitai", "Pony",
|
278 |
+
"Animagine", "Flux", "DiffuseCraft", "CFG", "Clip", "Inpaint", "Img2img", "Layer 2 Clip Skip"
|
279 |
+
]
|
280 |
+
|
281 |
+
# Civitai基础模型
|
282 |
+
CIVITAI_BASEMODEL_CN = {
|
283 |
+
"Pony": "Pony",
|
284 |
+
"Illustrious": "Illustrious",
|
285 |
+
"SDXL 1.0": "SDXL 1.0",
|
286 |
+
"SD 1.5": "SD 1.5",
|
287 |
+
"Flux.1 D": "Flux.1 D",
|
288 |
+
"Flux.1 S": "Flux.1 S"
|
289 |
+
}
|
290 |
+
|
291 |
+
# 界面模式
|
292 |
+
INTERFACE_MODES_CN = {
|
293 |
+
"Simple": "简单",
|
294 |
+
"Standard": "标准",
|
295 |
+
"Fast": "快速",
|
296 |
+
"LoRA": "LoRA"
|
297 |
+
}
|
298 |
+
|
299 |
+
# 模型类型
|
300 |
+
MODEL_TYPES_CN = {
|
301 |
+
"None": "无",
|
302 |
+
"Auto": "自动",
|
303 |
+
"Animagine": "Animagine",
|
304 |
+
"Pony": "Pony"
|
305 |
+
}
|
306 |
+
|
307 |
+
# 类型
|
308 |
+
GENRE_CN = {
|
309 |
+
"Anime": "动漫",
|
310 |
+
"Photo": "照片"
|
311 |
+
}
|
312 |
+
|
313 |
+
# 速度
|
314 |
+
SPEED_CN = {
|
315 |
+
"Fast": "快速",
|
316 |
+
"Standard": "标准",
|
317 |
+
"Heavy": "重度"
|
318 |
+
}
|
319 |
+
|
320 |
+
# 标签类型
|
321 |
+
TAG_TYPES_CN = {
|
322 |
+
"danbooru": "danbooru",
|
323 |
+
"e621": "e621",
|
324 |
+
"body": "身体",
|
325 |
+
"dress": "服装",
|
326 |
+
"all": "全部"
|
327 |
+
}
|
328 |
+
|
329 |
+
# 任务类型
|
330 |
+
TASK_TYPES_CN = {
|
331 |
+
"txt2img": "文本到图像",
|
332 |
+
"img2img": "图像到图像",
|
333 |
+
"inpaint": "图像修复",
|
334 |
+
"openpose ControlNet": "姿态控制网络",
|
335 |
+
"canny ControlNet": "边缘控制网络",
|
336 |
+
"mlsd ControlNet": "线条控制网络",
|
337 |
+
"scribble ControlNet": "涂鸦控制网络",
|
338 |
+
"softedge ControlNet": "软边缘控制网络",
|
339 |
+
"segmentation ControlNet": "分割控制网络",
|
340 |
+
"depth ControlNet": "深度控制网络",
|
341 |
+
"normalbae ControlNet": "法线控制网络",
|
342 |
+
"lineart ControlNet": "线稿控制网络",
|
343 |
+
"lineart_anime ControlNet": "动漫线稿控制网络",
|
344 |
+
"shuffle ControlNet": "混洗控制网络",
|
345 |
+
"ip2p ControlNet": "IP2P控制网络",
|
346 |
+
"optical pattern ControlNet": "光学图案控制网络",
|
347 |
+
"recolor ControlNet": "重着色控制网络",
|
348 |
+
"tile ControlNet": "瓦片控制网络",
|
349 |
+
"repaint ControlNet": "重绘控制网络"
|
350 |
+
}
|
351 |
+
|
352 |
+
# IP-Adapter模式
|
353 |
+
IP_ADAPTER_MODES_CN = {
|
354 |
+
"original": "原始",
|
355 |
+
"style": "风格"
|
356 |
+
}
|
357 |
+
|
358 |
+
# 推荐提示词类型
|
359 |
+
RECOM_PROMPT_TYPES_CN = {
|
360 |
+
"None": "无",
|
361 |
+
"Auto": "自动",
|
362 |
+
"Animagine": "Animagine",
|
363 |
+
"Pony": "Pony"
|
364 |
+
}
|
365 |
+
|
366 |
+
# 评分
|
367 |
+
RATING_CN = {
|
368 |
+
"general": "普通",
|
369 |
+
"sensitive": "敏感",
|
370 |
+
"questionable": "有疑问的",
|
371 |
+
"explicit": "成人内容"
|
372 |
+
}
|
373 |
+
|
374 |
+
# 纵横比
|
375 |
+
ASPECT_RATIO_CN = {
|
376 |
+
"square": "正方形",
|
377 |
+
"portrait": "人像",
|
378 |
+
"landscape": "风景"
|
379 |
+
}
|
380 |
+
|
381 |
+
# 提示词长度
|
382 |
+
LENGTH_CN = {
|
383 |
+
"very_short": "很短",
|
384 |
+
"short": "短",
|
385 |
+
"medium": "中等",
|
386 |
+
"long": "长",
|
387 |
+
"very_long": "很长"
|
388 |
+
}
|
389 |
+
|
390 |
+
# 身份保持度
|
391 |
+
IDENTITY_CN = {
|
392 |
+
"strict": "严格",
|
393 |
+
"lax": "宽松",
|
394 |
+
"none": "无"
|
395 |
+
}
|