diff --git a/change_app.py b/change_app.py index 08f579c..931e516 100644 --- a/change_app.py +++ b/change_app.py @@ -18,6 +18,7 @@ from config import * import websockets import asyncio import traceback +import re APP_ROOT = os.path.dirname(os.path.abspath(__file__)) @@ -454,25 +455,25 @@ def get_image_dimensions(image_path): print(f"Error: {e}") return None -def image_to_base64(file_path, mime_type=None): - if mime_type is None: - extension = file_path.split('.')[-1].lower() - mime_types = { - 'jpg': 'image/jpeg', - 'jpeg': 'image/jpeg', - 'png': 'image/png', - 'gif': 'image/gif', - 'webp': 'image/webp', - 'bmp': 'image/bmp' - } - mime_type = mime_types.get(extension, 'application/octet-stream') - - # 读取文件内容并编码为Base64 +def image_to_base64(file_path, with_head = True): + extension = file_path.split('.')[-1].lower() + mime_types = { + 'jpg': 'image/jpeg', + 'jpeg': 'image/jpeg', + 'png': 'image/png', + 'gif': 'image/gif', + 'webp': 'image/webp', + 'bmp': 'image/bmp' + } + mime_type = mime_types.get(extension, 'application/octet-stream') + with open(file_path, 'rb') as image_file: encoded_string = base64.b64encode(image_file.read()).decode('utf-8') - # 组合成Data URI格式 - return f"data:{mime_type};base64,{encoded_string}" + if with_head: + return f"data:{mime_type};base64,{encoded_string}" + else: + return encoded_string def upload_to_oss(image_path, object_name=None): # 配置信息(替换为你的实际信息) @@ -505,6 +506,102 @@ def upload_to_oss(image_path, object_name=None): print(f"上传失败: {str(e)}") return None +def get_image_from_json(json_str): + try: + data = json.loads(json_str) + parts = data["candidates"][0]["content"]["parts"] + base64_data = None + for part in parts: + if "inlineData" in part and "data" in part["inlineData"]: + base64_data = part["inlineData"]["data"] + break + + if base64_data is None: + print("未找到包含图片数据的部分") + return None + + base64_data = re.sub(r'\s+', '', base64_data) + image_data = base64.b64decode(base64_data) + return image_data + except Exception as e: + print(f"保存图片时发生错误: {e}") + return None + +import http.client +from io import BytesIO +def process_change_banana(human_filename, cloth_filename, output_format): + human_filepath = os.path.join(f'{APP_ROOT}/../input', human_filename) + suit_filepath = os.path.join(f'{APP_ROOT}/../input', cloth_filename) + + conn = http.client.HTTPSConnection("ai.juguang.chat") + payload = json.dumps({ + "contents": [ + { + "parts": [ + { + "text": "这是一张有人的图片" + }, + { + "inline_data": { + "mime_type": "image/jpeg", + "data": image_to_base64(human_filepath, False) + } + }, + { + "text": "这是另外一张有衣服,裤子或者裙子,鞋子,手表,耳环和其他各种可以穿戴在身上物品的图片" + }, + { + "inline_data": { + "mime_type": "image/jpeg", + "data": image_to_base64(suit_filepath, False) + } + }, + { + "text": "给第一张图片的人物,穿戴上第二张图片的衣服和配饰" + } + ] + } + ] + }) + headers = { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer sk-zLFhpbBQKWV4qohV4vD0AFR6Gaa7JwL0Q8zphh1CYFl2EqDM' + } + conn.request("POST", "/v1beta/models/gemini-2.5-flash-image-preview:generateContent", payload, headers) + res = conn.getresponse() + data = res.read() + decode_str = data.decode("utf-8") + + img_data = get_image_from_json(decode_str) + image_stream = BytesIO(img_data) + image = Image.open(image_stream) + jpg_name = f"{uuid.uuid4()}.png" + jpg_path_name = f'{APP_ROOT}/static/imgs/{jpg_name}' + image.save(jpg_path_name, quality=90) + upload_to_oss(jpg_path_name, jpg_name) + https_url = f'https://llyz.oss-cn-beijing.aliyuncs.com/{jpg_name}' + + if img_data: + if 'base64' in output_format: + return jsonify({ + "ret":0, + "state": 0, + "msg":"success", + "data":image_to_base64(jpg_path_name) + }) + else: + return jsonify({ + "ret":0, + "state": 0, + "msg":"success", + "url":https_url + }) + else: + return jsonify({ + "ret":-1, + "state": -1, + "msg":"failure" + }) def process_change_cloth(human_filename, cloth_filename, output_format, img_url, human_url, no2, tuodi, kuzi_url): w,h = get_image_dimensions(f'{APP_ROOT}/../input/{human_filename}') @@ -635,6 +732,9 @@ def do_change_cloth(): output_format = data.get('output_format') + if data['suit']: + return process_change_banana(human_filename, cloth_filename, output_format) + def check_type(var): if isinstance(var, bool): print(f"{var} 是布尔值no2") @@ -793,6 +893,11 @@ def change_cloth_base64(): if not tuodi: data['tuodi'] = False + + if not data.get('suit'): + data['suit'] = False + + # 在内部调用第二个HTTP请求 try: # 调用第二个API(可以是外部服务或自己的另一个端点) diff --git a/static/index.html b/static/index.html index 3267d29..ac0e33b 100644 --- a/static/index.html +++ b/static/index.html @@ -112,6 +112,9 @@ 设置 tuodi(拖地)
+ @@ -175,6 +178,7 @@ const kuziFile = document.getElementById('kuziInput').files[0]; const no2 = document.getElementById("no2Checkbox").checked; const tuodi = document.getElementById("tuodiCheckbox").checked; + const suit = document.getElementById("suitCheckbox").checked; if (!humanFile || !clothFile) { @@ -200,7 +204,8 @@ cloth_img: clothDataURL, // 包含完整前缀的Base64 output_format: "url", no2: no2, - tuodi:tuodi + tuodi:tuodi, + suit:suit }; if(kuziDataURL)