save code
This commit is contained in:
+109
-4
@@ -18,6 +18,7 @@ from config import *
|
|||||||
import websockets
|
import websockets
|
||||||
import asyncio
|
import asyncio
|
||||||
import traceback
|
import traceback
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
|
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
|
||||||
@@ -454,8 +455,7 @@ def get_image_dimensions(image_path):
|
|||||||
print(f"Error: {e}")
|
print(f"Error: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def image_to_base64(file_path, mime_type=None):
|
def image_to_base64(file_path, with_head = True):
|
||||||
if mime_type is None:
|
|
||||||
extension = file_path.split('.')[-1].lower()
|
extension = file_path.split('.')[-1].lower()
|
||||||
mime_types = {
|
mime_types = {
|
||||||
'jpg': 'image/jpeg',
|
'jpg': 'image/jpeg',
|
||||||
@@ -467,12 +467,13 @@ def image_to_base64(file_path, mime_type=None):
|
|||||||
}
|
}
|
||||||
mime_type = mime_types.get(extension, 'application/octet-stream')
|
mime_type = mime_types.get(extension, 'application/octet-stream')
|
||||||
|
|
||||||
# 读取文件内容并编码为Base64
|
|
||||||
with open(file_path, 'rb') as image_file:
|
with open(file_path, 'rb') as image_file:
|
||||||
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
|
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
|
||||||
|
|
||||||
# 组合成Data URI格式
|
if with_head:
|
||||||
return f"data:{mime_type};base64,{encoded_string}"
|
return f"data:{mime_type};base64,{encoded_string}"
|
||||||
|
else:
|
||||||
|
return encoded_string
|
||||||
|
|
||||||
def upload_to_oss(image_path, object_name=None):
|
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)}")
|
print(f"上传失败: {str(e)}")
|
||||||
return None
|
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):
|
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}')
|
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')
|
output_format = data.get('output_format')
|
||||||
|
|
||||||
|
if data['suit']:
|
||||||
|
return process_change_banana(human_filename, cloth_filename, output_format)
|
||||||
|
|
||||||
def check_type(var):
|
def check_type(var):
|
||||||
if isinstance(var, bool):
|
if isinstance(var, bool):
|
||||||
print(f"{var} 是布尔值no2")
|
print(f"{var} 是布尔值no2")
|
||||||
@@ -793,6 +893,11 @@ def change_cloth_base64():
|
|||||||
if not tuodi:
|
if not tuodi:
|
||||||
data['tuodi'] = False
|
data['tuodi'] = False
|
||||||
|
|
||||||
|
|
||||||
|
if not data.get('suit'):
|
||||||
|
data['suit'] = False
|
||||||
|
|
||||||
|
|
||||||
# 在内部调用第二个HTTP请求
|
# 在内部调用第二个HTTP请求
|
||||||
try:
|
try:
|
||||||
# 调用第二个API(可以是外部服务或自己的另一个端点)
|
# 调用第二个API(可以是外部服务或自己的另一个端点)
|
||||||
|
|||||||
+6
-1
@@ -112,6 +112,9 @@
|
|||||||
<input type="checkbox" id="tuodiCheckbox"> 设置 tuodi(拖地)
|
<input type="checkbox" id="tuodiCheckbox"> 设置 tuodi(拖地)
|
||||||
</label>
|
</label>
|
||||||
<br>
|
<br>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="suitCheckbox"> 设置 suit(套装)
|
||||||
|
</label>
|
||||||
<!-- <label>
|
<!-- <label>
|
||||||
<input type="checkbox" id="kuziCheckbox"> 设置 kuzi(裤子)
|
<input type="checkbox" id="kuziCheckbox"> 设置 kuzi(裤子)
|
||||||
</label> -->
|
</label> -->
|
||||||
@@ -175,6 +178,7 @@
|
|||||||
const kuziFile = document.getElementById('kuziInput').files[0];
|
const kuziFile = document.getElementById('kuziInput').files[0];
|
||||||
const no2 = document.getElementById("no2Checkbox").checked;
|
const no2 = document.getElementById("no2Checkbox").checked;
|
||||||
const tuodi = document.getElementById("tuodiCheckbox").checked;
|
const tuodi = document.getElementById("tuodiCheckbox").checked;
|
||||||
|
const suit = document.getElementById("suitCheckbox").checked;
|
||||||
|
|
||||||
|
|
||||||
if (!humanFile || !clothFile) {
|
if (!humanFile || !clothFile) {
|
||||||
@@ -200,7 +204,8 @@
|
|||||||
cloth_img: clothDataURL, // 包含完整前缀的Base64
|
cloth_img: clothDataURL, // 包含完整前缀的Base64
|
||||||
output_format: "url",
|
output_format: "url",
|
||||||
no2: no2,
|
no2: no2,
|
||||||
tuodi:tuodi
|
tuodi:tuodi,
|
||||||
|
suit:suit
|
||||||
};
|
};
|
||||||
|
|
||||||
if(kuziDataURL)
|
if(kuziDataURL)
|
||||||
|
|||||||
Reference in New Issue
Block a user