|
|
@@ -243,15 +243,17 @@ class AIImageGenerationService
|
|
|
// 更新状态为处理中
|
|
|
$task->updateStatus(MpGeneratePicTask::STATUS_PROCESSING);
|
|
|
|
|
|
- // $api_url = 'https://token.ithinkai.cn/v1/images/generations';
|
|
|
- $api_url = 'https://api.nonelinear.com/v1/images/generations';
|
|
|
+ // $api_url = 'https://token.ithinkai.cn/v1/images/generations'; // 备用地址1
|
|
|
+ // $api_url = 'https://api.nonelinear.com/v1/images/generations'; // 备用地址2
|
|
|
+ $api_url = 'https://ai-api.kkidc.com/v1/images/generations';
|
|
|
$isEditMode = false;
|
|
|
|
|
|
// 参考图片 - 如果有参考图则使用 /edits 接口
|
|
|
if ($task->ref_img_url) {
|
|
|
- // $api_url = 'https://token.ithinkai.cn/v1/images/edits';
|
|
|
- // $isEditMode = true;
|
|
|
- $api_url = 'https://api.nonelinear.com/v1/images/generations';
|
|
|
+ // $api_url = 'https://token.ithinkai.cn/v1/images/edits'; // 备用地址1
|
|
|
+ // $api_url = 'https://api.nonelinear.com/v1/images/generations'; // 备用地址2
|
|
|
+ $api_url = 'https://ai-api.kkidc.com/v1/images/edits';
|
|
|
+ $isEditMode = true;
|
|
|
}
|
|
|
|
|
|
dLog('generate')->info('开始调用GPT-Image2 API', ['task_id' => $task->task_id, 'mode' => $isEditMode ? 'edit' : 'generation']);
|
|
|
@@ -352,19 +354,16 @@ class AIImageGenerationService
|
|
|
'model' => 'gpt-image-2',
|
|
|
'prompt' => $task->prompt,
|
|
|
'n' => (int)$task->image_num,
|
|
|
+ 'quality' => 'auto', // 新接口必填参数:图像质量等级
|
|
|
+ 'response_format' => 'b64_json', // 新接口必填参数:返回格式
|
|
|
];
|
|
|
|
|
|
// 尺寸参数
|
|
|
if ($task->width && $task->height) {
|
|
|
$apiParams['size'] = $task->width . 'x' . $task->height;
|
|
|
+ } else {
|
|
|
+ $apiParams['size'] = 'auto'; // 新接口必填参数
|
|
|
}
|
|
|
-
|
|
|
- if ($task->ref_img_url) {
|
|
|
- $imageUrl = is_array($task->ref_img_url) ? $task->ref_img_url[0] : $task->ref_img_url;
|
|
|
- if ($imageUrl) {
|
|
|
- $apiParams['image'] = $imageUrl;
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
dLog('generate')->info('GPT-Image2 API参数', $apiParams);
|
|
|
logDB('generate', 'info', 'GPT-Image2任务提交', ['task_id' => $task->task_id, 'api_url' => $api_url, 'params' => $apiParams]);
|
|
|
@@ -453,8 +452,35 @@ class AIImageGenerationService
|
|
|
}
|
|
|
|
|
|
$result_urls = [];
|
|
|
- foreach ($responseData['data'] as $imageData) {
|
|
|
- if (isset($imageData['url'])) {
|
|
|
+ foreach ($responseData['data'] as $index => $imageData) {
|
|
|
+ // 优先处理 b64_json 格式(新接口返回格式)
|
|
|
+ if (isset($imageData['b64_json']) && !empty($imageData['b64_json'])) {
|
|
|
+ $base64Data = $imageData['b64_json'];
|
|
|
+ $imageStream = base64_decode($base64Data);
|
|
|
+
|
|
|
+ if ($imageStream === false) {
|
|
|
+ dLog('generate')->error('Base64解码失败', ['task_id' => $task->task_id, 'index' => $index]);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $pic_name = 'ai_generation_gpt_' . time() . '_' . uniqid() . '.png';
|
|
|
+
|
|
|
+ // 压缩PNG图片
|
|
|
+ $compressedData = compressImageStreamToSize($imageStream);
|
|
|
+ $url = uploadStreamByTos('image', $compressedData, $pic_name);
|
|
|
+
|
|
|
+ $result_urls[] = $url;
|
|
|
+
|
|
|
+ // 记录优化后的提示词(如果有)
|
|
|
+ if (isset($imageData['revised_prompt'])) {
|
|
|
+ dLog('generate')->info('图片生成优化提示词', [
|
|
|
+ 'task_id' => $task->task_id,
|
|
|
+ 'index' => $index,
|
|
|
+ 'revised_prompt' => $imageData['revised_prompt']
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ } elseif (isset($imageData['url']) && !empty($imageData['url'])) {
|
|
|
+ // 兼容旧的 url 格式(如果接口仍返回)
|
|
|
$url = $imageData['url'];
|
|
|
$pic_name = 'ai_generation_gpt_' . time() . '_' . uniqid();
|
|
|
$pic_ext = getImgExtFromUrl($url);
|
|
|
@@ -464,7 +490,6 @@ class AIImageGenerationService
|
|
|
$comporessed_data = compressRemoteImageUrlToSize($url);
|
|
|
$url = uploadStreamByTos('image', $comporessed_data, $pic_name);
|
|
|
} else {
|
|
|
- // 将图片另存到tos
|
|
|
$url = uploadStreamByTos('image', file_get_contents($url), $pic_name);
|
|
|
}
|
|
|
|