import json import base64 import os.path import uuid from datetime import datetime import requests from PIL import Image import io def submit_post(url: str, data: dict): """ Submit a POST request to the given URL with the given data. """ return requests.post(url, data=json.dumps(data)) def save_encoded_image(b64_image: str, output_path: str): """ Save the given image to the given output path. """ with open(output_path, "wb") as image_file: image_file.write(base64.b64decode(b64_image)) def encode_image(image_path): with open(image_path, "rb") as i: b64 = base64.b64encode(i.read()) return b64.decode("utf-8") # 打开一个JSON文件用于读取 def getJson(json_path): with open(json_path, 'r', encoding='utf-8') as f: # 从文件中加载JSON数据到字典 data = json.load(f) return data def printf(str): # 获取当前时间 now = datetime.now() # 格式化时间 current_time = now.strftime("%Y-%m-%d %H:%M:%S") # 打印当前时间 print(current_time + ' ' + str) # 获取图片的Base64编码 def get_image_base64_str(image_path): with open(image_path, 'rb') as image_file: # 使用Pillow库打开图像文件 image = Image.open(image_file) # 转换图像为RGB模式,因为JPEG不支持透明度 image = image.convert('RGB') # 创建一个字节流对象 buffer = io.BytesIO() # 将图像保存到字节流中,格式为JPEG image.save(buffer, format='JPEG') # 移动到字节流的开始位置 buffer.seek(0) # 将字节流中的数据编码为base64 encoded_image = base64.b64encode(buffer.read()) # 将编码后的图像数据转换为字符串,并构建完整的URL格式 base64_image_url = 'data:image/jpeg;base64,' + encoded_image.decode('utf-8') return base64_image_url # 将图片一切为四 def split_4_image(image_path, out_path): res = [] # 获取图片的宽度 img = Image.open(image_path) width, height = img.size new_width, new_height = width // 2, height // 2 # 左上角的图片 top_left = img.crop((0, 0, new_width, new_height)) f_name = str(uuid.uuid4()) + '.png' fi = os.path.join(out_path, f_name) res.append(f_name) top_left.save(fi) # 右上角的图片 top_right = img.crop((new_width, 0, width, new_height)) f_name = str(uuid.uuid4()) + '.png' fi = os.path.join(out_path, f_name) res.append(f_name) top_right.save(fi) # 左下角的图片 bottom_left = img.crop((0, new_height, new_width, height)) f_name = str(uuid.uuid4()) + '.png' fi = os.path.join(out_path, f_name) res.append(f_name) bottom_left.save(fi) # 右下角的图片 bottom_right = img.crop((new_width, new_height, width, height)) f_name = str(uuid.uuid4()) + '.png' fi = os.path.join(out_path, f_name) res.append(f_name) bottom_right.save(fi) return res # 图生图函数 def img2img(url,model_id, prompt_id, input_source_img, output_file): # JSON文件模板 templet_file = r'../JSON/' + str(model_id) + '_' + str(prompt_id) + '.json' # 模型图片 input_refer_img = '../Image/' + str(model_id) + '/' + str(prompt_id) + '.jpg' # 读取JSON文件 with open(templet_file, 'r', encoding='utf-8') as file: payload = json.load(file) # 用户输入的图片 source_img = encode_image(input_source_img) # 模型固定的参考图片 refer_img = encode_image(input_refer_img) # 在ControlNet的第一个图片中使用用户输入的图片,用此图片的人脸进行换脸操作 payload["alwayson_scripts"]["ControlNet"]["args"][0]["input_image"] = source_img # 图生图,风格参考图是输入 payload["init_images"] = [refer_img] payload["alwayson_scripts"]["ControlNet"]["args"][1]["input_image"] = refer_img # 调用SD服务 response = requests.post(url=f'{url}/sdapi/v1/img2img', json=payload) if response.status_code != 200: print(response.text) exit(0) r = response.json() # 保存图片 save_encoded_image(response.json()['images'][0], output_file)