一、本章诉求
由于前期设计的提示词均是英文输入,后期用户要求增加中文提示词输入,这个需求更改有两个方法,一个是修改comfyui工作流,另一个是修改前端,在前端将用户输入的中文翻译成英文,再推送到工作流中运行。
考虑到工作流功能较多,修改工作流也较为麻烦,本章选择修改前端的方式,封装一个前端vue翻译组件,实现提示词翻译功能的复用。
二、开发翻译接口
argos-translate 是一款基于OpenNMT(神经网络机器翻译框架)的离线翻译库,不依赖第三方翻译接口,支持翻译包括中文在内的 30 多种语言
python
pip install argostranslate
# add by ywz 20240925 argostranslate翻译 用于提示词翻译
import argostranslate.package
import argostranslate.translate
def argos_translate(query: str) -> str:
from_code = "zh"
to_code = "en"
argostranslate.package.update_package_index()
available_packages = argostranslate.package.get_available_packages()
package_to_install = next(
filter(
lambda x: x.from_code == from_code and x.to_code == to_code, available_packages
)
)
argostranslate.package.install_from_path(package_to_install.download())
translatedText = argostranslate.translate.translate(query, from_code, to_code)
return translatedText
from utils.argostranslate import argos_translate
@app.get("/translate")
def translate(query: str = Query()):
prompt = argos_translate(query)
return prompt
三、封装前端翻译组件
html
<template>
<div>
<p>
<span style="font-size: medium; color: #333333">{{ cardTitle }}</span>
<span style="font-size: smaller; color: grey; margin-left: 5px">可选</span>
</p>
<a-textarea
v-model="inputText"
:placeholder="placeholder"
:auto-size="{ minRows: 4, maxRows: 5 }"
/>
<p v-if="translationResult">翻译结果: {{ translationResult }}</p>
</div>
</template>
<script>
export default {
props: {
cardTitle: {
type: String,
default: '',
},
promptFlag: {
type: String,
default: '',
},
placeholderText: {
type: String,
default: '',
},
},
data() {
return {
inputText: '',
promptFlagText: this.promptFlag,
placeholder: this.placeholderText,
translationResult: ''
};
},
methods: {
translate() {
return new Promise((resolve, reject) => {
fetch(`/seg/translate?query=${encodeURIComponent(this.inputText)}`, {
method: "GET",
})
.then((response) => {
if (!response.ok) {
throw new Error('网络响应不正确');
}
return response.json();
})
.then((data) => {
console.log("Success:", data);
this.translationResult = data
if (this.promptFlagText === '正向') {
resolve(data); // 返回结果
} else {
if (data != '') {
let negativeInitPrompt = ",(worst quality:2.0),poorly drawn,bad anatomy,(bad proportions:1.3),ugly,disgusting,amputation,bugly,geometry,bad_prompt,multiple limbs,(bad hand:2.0),extra limb,(deformed fingers:2.0),mutated hands and fingers,disconnected limbs, geometry, bad_prompt,(missing fingers), (interlocked fingers:1.2), (extra digit and hands and fingers and legs and arms:1.4),(long fingers:1.2),(bad-artist-anime),(shinny skin, reflections on the skin, skin reflections:1.5)";
resolve(data + negativeInitPrompt);
} else {
let negativeInitPrompt = "(worst quality:2.0),poorly drawn,bad anatomy,(bad proportions:1.3),ugly,disgusting,amputation,bugly,geometry,bad_prompt,multiple limbs,(bad hand:2.0),extra limb,(deformed fingers:2.0),mutated hands and fingers,disconnected limbs, geometry, bad_prompt,(missing fingers), (interlocked fingers:1.2), (extra digit and hands and fingers and legs and arms:1.4),(long fingers:1.2),(bad-artist-anime),(shinny skin, reflections on the skin, skin reflections:1.5)";
resolve(negativeInitPrompt);
}
}
})
.catch((error) => {
console.error("Error:", error);
alert("'翻译出错: ' + error.message")
reject('翻译出错: ' + error.message);
});
});
},
},
};
</script>
<style scoped>
* {
margin: 0;
}
</style>
html
//html
<div style="padding-left: 20px; padding-right: 20px;margin-top: 20px">
<TranslationInput
ref="positiveTranslationInput"
:card-title="'正向提示词'"
:promptFlag="'正向'"
:placeholderText="'请输入正向提示词(中文)'"
@translationComplete="handlePositiveTranslation"
/>
</div>
<div style="padding-left: 20px; padding-right: 20px;margin-top: 20px">
<TranslationInput
ref="negativeTranslationInput"
:card-title="'负向提示词'"
:promptFlag="'负向'"
:placeholderText="'请输入负向提示词(中文)'"
@translationComplete="handleNegativeTranslation"
/>
</div>
//script
import TranslationInput from './TranslationInput.vue';
components: {TranslationInput},
confirmTranslation() {
this.$refs.positiveTranslationInput.translate()
.then(result => {
this.handlePositiveTranslation(result);
this.confirmNegativeTranslation()
})
},
confirmNegativeTranslation() {
this.$refs.negativeTranslationInput.translate()
.then(result => {
this.handleNegativeTranslation(result);
this.generate()
})
},
handlePositiveTranslation(result) {
this.positive = result;
},
handleNegativeTranslation(result) {
this.negative = result;
},