Python 调用 sora_image模型 API 实现图片生成与垫图
本文介绍了如何通过 Python 调用 API 实现图片生成,并支持单图/多图垫图的应用场景。内容分为三个部分:基础图片生成、单张垫图生成、多张垫图生成。代码均经过实践验证,并配有运行效果图。
文本生成图片
首先,实现一个最简单的文本提示生成图片的功能。
import http.client
import json
import ssl
import redef get_image_link(): # 定义函数,将所有逻辑放入函数内# 创建未验证的上下文ctx = ssl.create_default_context()ctx.check_hostname = Falsectx.verify_mode = ssl.CERT_NONEconn = http.client.HTTPSConnection("4o.zhangsan.shop", context=ctx)payload = json.dumps({"stream": True,"model": "sora_image","messages": [{"content": "画个牛马","role": "user"}]})headers = {'Content-Type': 'application/json','Authorization': 'Bearer sk-SUk0ji42J48U8mGIaHn8uA2G6nAyj9woaQvQNL1gRmFnaybD'}conn.request("POST", "/v1/chat/completions", payload, headers)res = conn.getresponse()image_links = []# 处理流式响应while True:line = res.readline().decode("utf-8")if not line:breakif line.startswith('data: '):# 提取JSON部分json_str = line[len('data: '):].strip()if json_str == '[DONE]':breaktry:data = json.loads(json_str)# 解析响应获取内容if 'choices' in data and data['choices']:delta = data['choices'][0].get('delta', {})content = delta.get('content', '')# 使用正则提取链接(补充了更精确的正则)url_match = re.search(r'https?://video\.chuanchuan\.cloud/[^\s\)]+', content)if url_match:image_url = url_match.group()# 解码URL中的特殊字符image_url = image_url.replace('\u0026', '&')image_links.append(image_url)except json.JSONDecodeError:continueconn.close()# 返回去重后的第一个有效链接if image_links:unique_links = list(set(image_links))return unique_links[0]return None # 这两个return现在在函数内部,正确# 调用函数并打印结果
if __name__ == "__main__":image_link = get_image_link() # 现在可以正确调用函数if image_link:print("提取到的图片链接:")print(image_link)else:print("未能提取到图片链接")
运行后即可得到图片链接,效果如下:
单个垫图的图片生成
如果希望基于某张图片进行风格迁移或二次创作,可以将本地图片作为“垫图”传入。
核心思路
- 将本地图片转为 Base64 编码;
- 在请求中附带图片数据;
- 提示模型基于该垫图生成新图。
原图:
代码实现:
import http.client
import json
import ssl
import re
import base64
from pathlib import Path # 用于处理本地文件路径def image_to_base64(image_path):"""将本地图片转换为Base64编码字符串"""# 检查图片文件是否存在if not Path(image_path).exists():raise FileNotFoundError(f"本地图片不存在:{image_path}")# 读取图片并编码为Base64with open(image_path, "rb") as f:base64_str = base64.b64encode(f.read()).decode("utf-8")# 返回带格式的Base64(供API识别图片类型,如jpg/png)image_ext = Path(image_path).suffix.lower() # 获取图片后缀(.jpg/.png等)if image_ext == ".jpg" or image_ext == ".jpeg":return f"data:image/jpeg;base64,{base64_str}"elif image_ext == ".png":return f"data:image/png;base64,{base64_str}"else:raise ValueError("仅支持JPG/JPEG、PNG格式的本地图片")def generate_image_with_reference(local_image_path):"""基于本地垫图生成新图片,返回生成结果的图片链接"""# 1. 先将本地垫图转为Base64try:reference_base64 = image_to_base64(local_image_path)except Exception as e:print(f"处理本地垫图失败:{str(e)}")return None# 2. 配置SSL上下文(测试用,生产环境建议移除)ctx = ssl.create_default_context()ctx.check_hostname = Falsectx.verify_mode = ssl.CERT_NONE# 3. 构建API请求conn = http.client.HTTPSConnection("4o.zhangsan.shop", context=ctx)# 请求体:添加"reference_image"字段传递垫图Base64(字段名需按API文档调整,如"image"或"ref_image")payload = json.dumps({"stream": True,"model": "sora_image","messages": [{"content": [# 文本提示(描述基于垫图的生成需求,如“转吉卜力风格”){"type": "text", "text": "转吉卜力风格"},# 垫图数据(Base64格式){"type": "image_url", "image_url": {"url": reference_base64}}],"role": "user"}]})headers = {'Content-Type': 'application/json','Authorization': 'Bearer sk-SUk0ji42J48U8mGIaHn8uA2G6nAyj9woaQvQNL1gRmFnaybD' # 你的API密钥}# 4. 发送请求并处理流式响应conn.request("POST", "/v1/chat/completions", payload, headers)res = conn.getresponse()image_links = []while True:line = res.readline().decode("utf-8")if not line:breakif line.startswith('data: '):json_str = line[len('data: '):].strip()if json_str == '[DONE]':breaktry:data = json.loads(json_str)if 'choices' in data and data['choices']:delta = data['choices'][0].get('delta', {})content = delta.get('content', '')# 提取生成结果的图片链接url_match = re.search(r'https?://video\.chuanchuan\.cloud/[^\s\)]+', content)if url_match:image_url = url_match.group().replace('\u0026', '&') # 解码URL特殊字符image_links.append(image_url)except json.JSONDecodeError:continueconn.close()# 5. 返回去重后的有效链接if image_links:return list(set(image_links))[0]return None# ------------------- 调用示例 -------------------
if __name__ == "__main__":# 替换为你的本地垫图路径(如:"C:/images/my_reference.png" 或 "./reference.jpg")LOCAL_IMAGE_PATH = "img.png"generated_link = generate_image_with_reference(LOCAL_IMAGE_PATH)if generated_link:print("基于垫图生成的图片链接:")print(generated_link)else:print("垫图生成失败或未提取到链接")
运行效果如下:
多个图片垫图
有时希望结合两张图片进行风格融合或元素合成,此时可以传入多个 Base64 图片。
原图:
代码:
import http.client
import json
import ssl
import re
import base64
from pathlib import Path # 用于处理本地文件路径def image_to_base64(image_path):"""将本地图片转换为Base64编码字符串"""# 检查图片文件是否存在if not Path(image_path).exists():raise FileNotFoundError(f"本地图片不存在:{image_path}")# 读取图片并编码为Base64with open(image_path, "rb") as f:base64_str = base64.b64encode(f.read()).decode("utf-8")# 返回带格式的Base64(供API识别图片类型,如jpg/png)image_ext = Path(image_path).suffix.lower() # 获取图片后缀(.jpg/.png等)if image_ext == ".jpg" or image_ext == ".jpeg":return f"data:image/jpeg;base64,{base64_str}"elif image_ext == ".png":return f"data:image/png;base64,{base64_str}"else:raise ValueError("仅支持JPG/JPEG、PNG格式的本地图片")def generate_image_with_references(local_image_paths):"""基于多个本地垫图生成新图片,返回生成结果的图片链接"""# 1. 将所有本地垫图转为Base64try:reference_base64s = []for path in local_image_paths:reference_base64s.append(image_to_base64(path))except Exception as e:print(f"处理本地垫图失败:{str(e)}")return None# 2. 配置SSL上下文(测试用,生产环境建议移除)ctx = ssl.create_default_context()ctx.check_hostname = Falsectx.verify_mode = ssl.CERT_NONE# 3. 构建API请求conn = http.client.HTTPSConnection("4o.zhangsan.shop", context=ctx)# 创建消息内容列表,先添加文本提示,再添加所有图片message_content = [# 文本提示(描述基于垫图的生成需求){"type": "text", "text": "结合提供的图片,转吉卜力风格"}]# 添加所有垫图数据for base64_str in reference_base64s:message_content.append({"type": "image_url","image_url": {"url": base64_str}})# 请求体:包含多个垫图payload = json.dumps({"stream": True,"model": "sora_image","messages": [{"content": message_content,"role": "user"}]})headers = {'Content-Type': 'application/json','Authorization': 'Bearer sk-SUk0ji42J48U8mGIaHn8uA2G6nAyj9woaQvQNL1gRmFnaybD' # 你的API密钥}# 4. 发送请求并处理流式响应conn.request("POST", "/v1/chat/completions", payload, headers)res = conn.getresponse()image_links = []while True:line = res.readline().decode("utf-8")if not line:breakif line.startswith('data: '):json_str = line[len('data: '):].strip()if json_str == '[DONE]':breaktry:data = json.loads(json_str)if 'choices' in data and data['choices']:delta = data['choices'][0].get('delta', {})content = delta.get('content', '')# 提取生成结果的图片链接url_match = re.search(r'https?://video\.chuanchuan\.cloud/[^\s\)]+', content)if url_match:image_url = url_match.group().replace('\u0026', '&') # 解码URL特殊字符image_links.append(image_url)except json.JSONDecodeError:continueconn.close()# 5. 返回去重后的有效链接if image_links:return list(set(image_links))[0]return None# ------------------- 调用示例 -------------------
if __name__ == "__main__":# 替换为你的本地垫图路径列表LOCAL_IMAGE_PATHS = ["img.png", "img_1.png"] # 支持多个图片路径generated_link = generate_image_with_references(LOCAL_IMAGE_PATHS)if generated_link:print("基于多个垫图生成的图片链接:")print(generated_link)else:print("垫图生成失败或未提取到链接")
效果如下:
同理支持三个图片(失败率高,建议最多两个图片)