From c57e47fe4b8ae0c93f43b0a31acd0b7a22a9ccde Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Thu, 4 Sep 2025 11:51:32 +0800 Subject: [PATCH] 'commit' --- dsLightRag/Liblib/Kit/PuLIDGenerator.py | 3 +- .../PuLIDGenerator.cpython-310.pyc | Bin 0 -> 3296 bytes dsLightRag/Routes/CopyFaceRoute.py | 176 ++++++++++ .../__pycache__/CopyFaceRoute.cpython-310.pyc | Bin 0 -> 4507 bytes dsLightRag/Start.py | 2 + dsLightRag/static/LibLib/copyface.html | 301 ++++++++++++++++++ 6 files changed, 481 insertions(+), 1 deletion(-) create mode 100644 dsLightRag/Liblib/Kit/__pycache__/PuLIDGenerator.cpython-310.pyc create mode 100644 dsLightRag/Routes/CopyFaceRoute.py create mode 100644 dsLightRag/Routes/__pycache__/CopyFaceRoute.cpython-310.pyc create mode 100644 dsLightRag/static/LibLib/copyface.html diff --git a/dsLightRag/Liblib/Kit/PuLIDGenerator.py b/dsLightRag/Liblib/Kit/PuLIDGenerator.py index 449a585e..b35e3fb2 100644 --- a/dsLightRag/Liblib/Kit/PuLIDGenerator.py +++ b/dsLightRag/Liblib/Kit/PuLIDGenerator.py @@ -1,7 +1,8 @@ import json from Config.Config import OBS_BUCKET, OBS_SERVER -from LibLibGenerator import LibLibGenerator +from Liblib.Kit.LibLibGenerator import LibLibGenerator + class PuLIDGenerator: def __init__(self): diff --git a/dsLightRag/Liblib/Kit/__pycache__/PuLIDGenerator.cpython-310.pyc b/dsLightRag/Liblib/Kit/__pycache__/PuLIDGenerator.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34cd424949d592a16acb45f5e562a24175855504 GIT binary patch literal 3296 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 literal 0 HcmV?d00001 diff --git a/dsLightRag/Routes/CopyFaceRoute.py b/dsLightRag/Routes/CopyFaceRoute.py new file mode 100644 index 00000000..a61f3e56 --- /dev/null +++ b/dsLightRag/Routes/CopyFaceRoute.py @@ -0,0 +1,176 @@ +import json +import logging +import os +from typing import Optional, List + +from fastapi import APIRouter, HTTPException +from pydantic import BaseModel + +from Liblib.Kit.PuLIDGenerator import PuLIDGenerator + +# 创建路由路由器 +router = APIRouter(prefix="/api/copyface", tags=["人像换脸"]) + +# 配置日志 +logger = logging.getLogger(__name__) + +# JSON配置文件路径 +COPY_FACE_CONFIG_PATH = os.path.join(os.path.dirname(__file__), "..", "Liblib", "Data", "copy_face_image_data.json") + +class CopyFaceRequest(BaseModel): + image_url: str + +class ModelSample(BaseModel): + name: str + template_uuid: str + steps: int + width: int + height: int + cfgScale: float + sampler: str + seed: int + prompt: str + negative_prompt: Optional[str] = None + reference_image_url: str + control_weight: float + +@router.get("/samples", response_model=List[ModelSample]) +async def get_available_samples(): + """ + 获取所有可用的生成样例配置 + + Returns: + 包含所有可用模型样例的列表 + """ + try: + # 读取配置文件 + with open(COPY_FACE_CONFIG_PATH, 'r', encoding='utf-8') as f: + config_data = json.load(f) + + # 返回所有模型配置 + return config_data["models"] + + except FileNotFoundError: + logger.error(f"配置文件未找到: {COPY_FACE_CONFIG_PATH}") + raise HTTPException(status_code=404, detail="配置文件未找到") + except json.JSONDecodeError: + logger.error(f"配置文件格式错误: {COPY_FACE_CONFIG_PATH}") + raise HTTPException(status_code=500, detail="配置文件格式错误") + except Exception as e: + logger.error(f"获取样例配置失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"获取样例配置失败: {str(e)}") + +@router.post("/generate", response_model=dict) +async def generate_copy_face(request: CopyFaceRequest): + """ + 根据提供的图片URL生成模拟人脸图片(使用默认配置) + + Args: + request: 包含图片URL的请求体 + + Returns: + 包含生成图片OBS地址的字典 + """ + try: + # 读取默认配置(第一个模型) + with open(COPY_FACE_CONFIG_PATH, 'r', encoding='utf-8') as f: + config_data = json.load(f) + + default_config = config_data["models"][0] + + # 使用默认配置 + generator = PuLIDGenerator() + + # 设置默认参数 + generator.set_default_params( + template_uuid=default_config["template_uuid"], + steps=default_config["steps"], + width=default_config["width"], + height=default_config["height"] + ) + + # 生成图像 + obs_url = generator.generate_image( + prompt=default_config["prompt"], + reference_image_url=request.image_url, + control_weight=default_config["control_weight"] + ) + + if obs_url: + logger.info(f"人像换脸生成成功,OBS地址: {obs_url}") + return { + "status": "success", + "obs_url": obs_url, + "message": "人像换脸生成成功", + "model_used": default_config["name"] + } + else: + logger.error("人像换脸生成失败") + raise HTTPException(status_code=500, detail="人像换脸生成失败") + + except Exception as e: + logger.error(f"人像换脸请求处理失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"人像换脸请求处理失败: {str(e)}") + +@router.post("/generate/{model_name}", response_model=dict) +async def generate_copy_face_with_model(model_name: str, request: CopyFaceRequest): + """ + 根据指定的模型名称和图片URL生成模拟人脸图片 + + Args: + model_name: 模型名称(如:炫酷机甲美女_majicflus) + request: 包含图片URL的请求体 + + Returns: + 包含生成图片OBS地址的字典 + """ + try: + # 读取配置文件 + with open(COPY_FACE_CONFIG_PATH, 'r', encoding='utf-8') as f: + config_data = json.load(f) + + # 查找指定的模型配置 + model_config = None + for model in config_data["models"]: + if model["name"] == model_name: + model_config = model + break + + if not model_config: + raise HTTPException(status_code=404, detail=f"未找到模型: {model_name}") + + # 使用指定配置 + generator = PuLIDGenerator() + + # 设置参数 + generator.set_default_params( + template_uuid=model_config["template_uuid"], + steps=model_config["steps"], + width=model_config["width"], + height=model_config["height"] + ) + + # 生成图像 + obs_url = generator.generate_image( + prompt=model_config["prompt"], + reference_image_url=request.image_url, + control_weight=model_config["control_weight"] + ) + + if obs_url: + logger.info(f"人像换脸生成成功,模型: {model_name}, OBS地址: {obs_url}") + return { + "status": "success", + "obs_url": obs_url, + "message": "人像换脸生成成功", + "model_used": model_name + } + else: + logger.error(f"人像换脸生成失败,模型: {model_name}") + raise HTTPException(status_code=500, detail="人像换脸生成失败") + + except HTTPException: + raise + except Exception as e: + logger.error(f"人像换脸请求处理失败: {str(e)}") + raise HTTPException(status_code=500, detail=f"人像换脸请求处理失败: {str(e)}") \ No newline at end of file diff --git a/dsLightRag/Routes/__pycache__/CopyFaceRoute.cpython-310.pyc b/dsLightRag/Routes/__pycache__/CopyFaceRoute.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d018946f4bf8b277e941fb51ff03b7278e0d0723 GIT binary patch literal 4507 zcmc(iTXPi06@aH_dS_;@S_Bd-7e`5)iz>E=bFm$TIAAU|jx1DQm&;qEriSg_W#!$S zb}*9IGU&seFoP++rrPN`%=ndOpp`Y=-yD zk$jfx<11!+m0ZbJ%@G!736^B3xmdpMF^#2JW?Ewzo;YIU`=Q>$vQW>e`f8pYU&B`L z7+;;!SnrI^RqgS_EWZwtylf` zFtSG*+;9_opp6dd(%w}M%3jT_NIFvX189kF8QZzr3j;1>`thfp8r%M2fh(OsBIA#` zK7Z0;eL^I`!Ycd(3L>GUh-z8>OJ4xB&wr`x43+ zeW&ev4DKehn{Y?ZSnYPZU5|sO5_yZ;+{kIrpKQ0M;Ev4t_81J4@PBA zjhDc$FK{Pnkt<=5aKUSxRRFUkGX<{}2(RKCP<997A`R{k85BJzvM5%7kVd%{$XK!B zxq(=ZtvZU%d_|>|*oNK*RA~NM5DCpDcmA@_0`r1;llI2w1AJWig8Ow?2^?1quiQ3g zxH6GMe}}&>LHwLdemT$r!U)ruF=L!cPicWZYc#YuGDV)z7^NE3ju=F%*$-%b?f@Yg z{+@+@gRodmdq&#>8UdYnDC!AfvnDeGa!z|)p9Af{VivPmd`3S^Ku;gHCq}w76Srvs zeL9-)i3-uCbfQi6DVyma(a?`{+fA~rwrCuqQ~E*u0675bBJ}ZV2jE(GdR#vsZ6ifBELonfZ?{D_tda^B@#8e^^z}Li6O&=IOV) zEwnDqHGlhZG#sookH5AscTwp}B0h&@fu3=iBqLo_YyTTbDUE|We4dgwb~luMKGz%5roTq3twoW0h(cIxJt z-z;3Y0!IIZM%R3Sjxx}8QkOrPZ@jzkmp6w829uI{bzYNwTX&5;>+IOFb-S~5*XWL& zk2zyoo_btTq@bj*sF_@`qg>&mUa-RpYizp^o{(n6E0uuQF^*LcgBOuKPwd$>x{c#k zL`v}v%2l)gA4yRrA+U<&l0vN{yem#HL}Xuy2afv!c);BUbZm#f*PzS)3JCp>ZfErr zS^u8|P3c((mJEsHD$-BvL;7dpVNjclZ!AUo1ecbGSX=;)buQeTJ3#|`D+bNJJA#I& zpdk=6`u_+T9fO9MIc>@a=n-v-Ht2Y)VK6JFfwYy3E13YjG%Avw=MuXFZMBV!*L%BgR&MRxfC+JWnw|K_|gri-&MbvOczo^|!+@H8BlA zW~v}Voz+3QVRi)>YIn6o;~>b)gQg0yHQ_(dI~XFZ+4oyBms_V!-?)Ab1LEBE`4h*U z-aXQevx{@BmoLDc3%hO9b?e&k8z21*V)5pOzh1cfMznr!T|1$SDX~SAx&&jp6Bz-SUV5SQrPTE#l-zX$t`sJvmZAw+ZCxkuYS$4@t3x^U~-$%{Qj!PyeEWg^ail2i%Wh2*pMe7%sBchtOoa=!TWRsk_3h`ZBW^W>Eqq zFbNY6pf)Ynik|om){ze4dnj5@#4}y@HMWYcKWV~$@z_J;Y9zwCSpDIrD zb{^cx;eHHiJ`Mm#BqK7N!q_pscjO9wSQAHOLSc)I@Ih>6Bd9(?;vC+7@6$v zAY|juB4=Y3G9}xd$4UWr`o${_g$`22BBUI=11Y*f3hbd%#up<6!jVF_16HsyH(b7B*4|LlEt~Gyu_|~h7f)d89qdU(Q{E;|Ox48WsJI!$-O#h)^XPF7l!N_I zZjK46zZ(QlC>2qN(i9{r6n^?=l=hP4nbhBAk`7GD0+Uies0`_F=}9m<_$9?(k!vHO56Sck4y(mAk>l4ha1?7S;p)H?_j>1DfDF;KhpR6O? zn<6@t1C4_bmF-1Gpos2u7Y + + + + + 人像换脸生成器 + + + +
+

🎭 人像换脸生成器

+ +
+ + +
+ +
+ + +
+ +
+

参考图片预览:

+ 参考图片预览 +
+ + + + +
+
+

正在生成中,请稍候...

+
+ + +
+ + + + \ No newline at end of file