```
feat(api): 移除gpt-image-2参考图强制验证并优化图像处理逻辑 移除对gpt-image-2模型的参考图上传强制验证,支持无参考图时调用生成接口, 同时优化图像URL提取和处理逻辑以支持不同响应格式 BREAKING CHANGE: gpt-image-2不再强制要求上传参考图 ```
This commit is contained in:
parent
3610bedb39
commit
3df902963d
@ -91,17 +91,15 @@ def generate():
|
||||
|
||||
image_data = data.get("image_data", [])
|
||||
if model_value == "gpt-image-2":
|
||||
if not image_data:
|
||||
return jsonify({"error": "gpt-image-2 编辑模式至少需要上传 1 张参考图"}), 400
|
||||
|
||||
payload = {
|
||||
"prompt": prompt,
|
||||
"model": model_value,
|
||||
"images": [{"image_url": img} for img in image_data],
|
||||
"size": data.get("size") or "2048x2048",
|
||||
"quality": "high",
|
||||
"output_format": "png",
|
||||
}
|
||||
if image_data:
|
||||
payload["images"] = [{"image_url": img} for img in image_data]
|
||||
else:
|
||||
payload = {
|
||||
"prompt": prompt,
|
||||
|
||||
@ -37,6 +37,7 @@ class Config:
|
||||
CHAT_API = f"{AI_BASE_URL}/v1/chat/completions"
|
||||
VIDEO_GEN_API = f"{AI_BASE_URL}/v2/videos/generations"
|
||||
VIDEO_POLL_API = f"{AI_BASE_URL}/v2/videos/generations/{{task_id}}"
|
||||
GPT_IMAGE_GENERATION_API = "https://nas.4x4g.com:8317/v1/images/generations"
|
||||
GPT_IMAGE_EDIT_API = "https://nas.4x4g.com:8317/v1/images/edits"
|
||||
GPT_IMAGE_EDIT_KEY = "sk-vDmmYNzoe7UjWskKx"
|
||||
|
||||
|
||||
@ -34,12 +34,18 @@ def validate_generation_request(user, data):
|
||||
model_value = data.get("model")
|
||||
is_gemini_flash_image_preview = model_value == "gemini-3.1-flash-image-preview"
|
||||
is_gpt_image_edit = model_value == "gpt-image-2"
|
||||
image_data = data.get("image_data", [])
|
||||
has_reference_images = bool(image_data)
|
||||
|
||||
if isinstance(is_premium, str):
|
||||
is_premium = is_premium.lower() in ("1", "true", "yes", "on")
|
||||
|
||||
# gpt-image-2 走独立的 edits 接口,其余模型沿用现有 generations 接口
|
||||
target_api = Config.GPT_IMAGE_EDIT_API if is_gpt_image_edit else Config.AI_API
|
||||
# gpt-image-2 有参考图走 edits,无参考图走 generations;其它模型沿用现有 generations 接口
|
||||
target_api = (
|
||||
(Config.GPT_IMAGE_EDIT_API if has_reference_images else Config.GPT_IMAGE_GENERATION_API)
|
||||
if is_gpt_image_edit
|
||||
else Config.AI_API
|
||||
)
|
||||
api_key = None
|
||||
use_trial = False
|
||||
|
||||
@ -70,7 +76,11 @@ def validate_generation_request(user, data):
|
||||
else:
|
||||
api_key = Config.TRIAL_KEY
|
||||
|
||||
target_api = Config.GPT_IMAGE_EDIT_API if is_gpt_image_edit else Config.TRIAL_API
|
||||
target_api = (
|
||||
(Config.GPT_IMAGE_EDIT_API if has_reference_images else Config.GPT_IMAGE_GENERATION_API)
|
||||
if is_gpt_image_edit
|
||||
else Config.TRIAL_API
|
||||
)
|
||||
use_trial = True
|
||||
|
||||
# 计算本次任务消耗
|
||||
|
||||
@ -150,6 +150,14 @@ def _extract_b64_images(result):
|
||||
return images
|
||||
|
||||
|
||||
def _extract_image_urls(result):
|
||||
urls = []
|
||||
for item in result.get("data", []) or []:
|
||||
if isinstance(item, dict) and item.get("url"):
|
||||
urls.append(item["url"])
|
||||
return urls
|
||||
|
||||
|
||||
def _process_gpt_image_edit(app, user_id, task_id, payload, api_key, target_api, cost, use_trial):
|
||||
headers = {
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
@ -173,7 +181,28 @@ def _process_gpt_image_edit(app, user_id, task_id, payload, api_key, target_api,
|
||||
result = response.json()
|
||||
b64_images = _extract_b64_images(result)
|
||||
if not b64_images:
|
||||
raise Exception("gpt-image-2 未返回可用图片数据")
|
||||
url_images = _extract_image_urls(result)
|
||||
if not url_images:
|
||||
raise Exception("gpt-image-2 未返回可用图片数据")
|
||||
|
||||
processed_data = [{"url": image_url, "thumb": image_url} for image_url in url_images]
|
||||
new_record = GenerationRecord(
|
||||
user_id=user_id,
|
||||
prompt=payload.get("prompt"),
|
||||
model=payload.get("model"),
|
||||
cost=cost,
|
||||
image_urls=json.dumps(processed_data),
|
||||
)
|
||||
db.session.add(new_record)
|
||||
db.session.commit()
|
||||
|
||||
system_logger.info("gpt-image-2 生图任务完成", user_id=user_id, task_id=task_id, model=payload.get("model"))
|
||||
redis_client.setex(
|
||||
f"task:{task_id}",
|
||||
3600,
|
||||
json.dumps({"status": "complete", "urls": url_images, "record_id": new_record.id}),
|
||||
)
|
||||
return
|
||||
|
||||
processed_data = []
|
||||
final_urls = []
|
||||
|
||||
@ -552,18 +552,6 @@ document.getElementById('submitBtn').onclick = async () => {
|
||||
}
|
||||
|
||||
// UI 锁定
|
||||
if (document.getElementById('modelSelect').value === GPT_IMAGE_EDIT_MODEL && uploadedFiles.length === 0) {
|
||||
return showToast('gpt-image-2 requires a reference image', 'warning');
|
||||
}
|
||||
|
||||
if (document.getElementById('modelSelect').value === GPT_IMAGE_EDIT_MODEL && uploadedFiles.length === 0) {
|
||||
return showToast('gpt-image-2 妯″瀷蹇呴』涓婁紶鍙傝€冨浘', 'warning');
|
||||
}
|
||||
|
||||
if (document.getElementById('modelSelect').value === GPT_IMAGE_EDIT_MODEL && uploadedFiles.length === 0) {
|
||||
return showToast('gpt-image-2 requires a reference image', 'warning');
|
||||
}
|
||||
|
||||
btn.disabled = true;
|
||||
const btnText = btn.querySelector('span');
|
||||
btnText.innerText = uploadedFiles.length > 0 ? "正在同步参考图..." : "正在开启 AI 引擎...";
|
||||
|
||||
@ -664,11 +664,6 @@
|
||||
const num = parseInt(document.getElementById('numSelect').value);
|
||||
const isPremium = document.getElementById('isPremium').checked;
|
||||
|
||||
if (model === GPT_IMAGE_EDIT_MODEL && uploadedFiles.length === 0) {
|
||||
showToast('gpt-image-2 模型必须上传参考图', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示加载状态
|
||||
document.getElementById('placeholder').classList.add('hidden');
|
||||
document.getElementById('placeholder').classList.add('hidden');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user