Преглед изворни кода

gpt-image-2图片模型兼容图生图格式

lh пре 2 дана
родитељ
комит
14a2573153
1 измењених фајлова са 63 додато и 21 уклоњено
  1. 63 21
      app/Services/AIGeneration/AIImageGenerationService.php

+ 63 - 21
app/Services/AIGeneration/AIImageGenerationService.php

@@ -271,40 +271,80 @@ class AIImageGenerationService
             // 根据是否有参考图选择不同的请求方式
             if ($isEditMode) {
                 // 使用原生 cURL 处理 multipart/form-data 格式
-                $imageUrl = is_array($task->ref_img_url) ? $task->ref_img_url[0] : $task->ref_img_url;
+                $imageUrls = is_array($task->ref_img_url) ? $task->ref_img_url : [$task->ref_img_url];
                 
-                dLog('generate')->info('下载参考图片', ['image_url' => $imageUrl]);
+                // 限制最多4张参考图
+                $imageUrls = array_slice($imageUrls, 0, 4);
                 
-                // 下载图片内容
-                $imageContent = @file_get_contents($imageUrl);
-                if ($imageContent === false) {
-                    throw new \Exception('下载参考图片失败: ' . $imageUrl);
-                }
-                
-                dLog('generate')->info('参考图片下载完成', ['size' => strlen($imageContent)]);
+                dLog('generate')->info('下载参考图片', ['image_urls' => $imageUrls, 'count' => count($imageUrls)]);
                 
-                // 保存为临时文件(cURL 需要真实文件路径)
-                $extension = pathinfo(parse_url($imageUrl, PHP_URL_PATH), PATHINFO_EXTENSION) ?: 'png';
-                $tempFile = tempnam(sys_get_temp_dir(), 'gpt_img_') . '.' . $extension;
-                file_put_contents($tempFile, $imageContent);
+                // 下载所有参考图片并保存为临时文件
+                $tempFiles = [];
+                foreach ($imageUrls as $index => $imageUrl) {
+                    $imageContent = @file_get_contents($imageUrl);
+                    if ($imageContent === false) {
+                        dLog('generate')->warning('下载参考图片失败,跳过', ['image_url' => $imageUrl]);
+                        continue;
+                    }
+                    
+                    dLog('generate')->info('参考图片下载完成', ['index' => $index, 'size' => strlen($imageContent)]);
+                    
+                    // 保存为临时文件(cURL 需要真实文件路径)
+                    $extension = pathinfo(parse_url($imageUrl, PHP_URL_PATH), PATHINFO_EXTENSION) ?: 'png';
+                    $tempFile = tempnam(sys_get_temp_dir(), 'gpt_img_') . '.' . $extension;
+                    file_put_contents($tempFile, $imageContent);
+                    
+                    $tempFiles[] = [
+                        'path' => $tempFile,
+                        'extension' => $extension
+                    ];
+                    
+                    dLog('generate')->info('临时文件创建成功', ['file' => $tempFile, 'size' => filesize($tempFile)]);
+                }
                 
-                dLog('generate')->info('临时文件创建成功', ['file' => $tempFile, 'size' => filesize($tempFile)]);
+                if (empty($tempFiles)) {
+                    throw new \Exception('所有参考图片下载失败');
+                }
                 
                 // 构建 POST 字段
                 $postFields = [
-                    'image' => new \CURLFile($tempFile, 'image/' . $extension, 'image.' . $extension),
                     'prompt' => $task->prompt,
                     'model' => 'gpt-image-2',
-                    'n' => (int)$task->image_num,
+                    'n' => (string)$task->image_num, // 新接口要求字符串类型
+                    'response_format' => 'b64_json', // 新接口必填参数
                 ];
                 
-                // 尺寸参数
+                // 尺寸参数(必填)
                 if ($task->width && $task->height) {
                     $postFields['size'] = $task->width . 'x' . $task->height;
+                } else {
+                    $postFields['size'] = '1024x1024'; // 默认尺寸
                 }
                 
-                dLog('generate')->info('GPT-Image2 API参数(编辑模式-cURL)', ['api_url' => $api_url, 'prompt' => $task->prompt, 'size' => ($task->width . 'x' . $task->height), 'n' => (int)$task->image_num]);
-                logDB('generate', 'info', 'GPT-Image2任务提交(编辑模式)', ['task_id' => $task->task_id, 'api_url' => $api_url, 'image_url' => $imageUrl, 'prompt' => $task->prompt]);
+                // 添加参考图片文件(支持多图,新接口要求使用 image 字段名)
+                foreach ($tempFiles as $index => $tempFile) {
+                    $fieldName = 'image'; // 新接口统一使用 image 字段名
+                    $postFields[$fieldName] = new \CURLFile(
+                        $tempFile['path'], 
+                        'image/' . $tempFile['extension'], 
+                        'image' . ($index + 1) . '.' . $tempFile['extension']
+                    );
+                }
+                
+                dLog('generate')->info('GPT-Image2 API参数(编辑模式-cURL)', [
+                    'api_url' => $api_url, 
+                    'prompt' => $task->prompt, 
+                    'size' => $postFields['size'], 
+                    'n' => $postFields['n'],
+                    'response_format' => $postFields['response_format'],
+                    'image_count' => count($tempFiles)
+                ]);
+                logDB('generate', 'info', 'GPT-Image2任务提交(编辑模式)', [
+                    'task_id' => $task->task_id, 
+                    'api_url' => $api_url, 
+                    'image_urls' => $imageUrls, 
+                    'prompt' => $task->prompt
+                ]);
                 
                 $startTime = microtime(true);
                 
@@ -335,8 +375,10 @@ class AIImageGenerationService
                 $curlErrno = curl_errno($ch);
                 curl_close($ch);
                 
-                // 删除临时文件
-                @unlink($tempFile);
+                // 删除所有临时文件
+                foreach ($tempFiles as $tempFile) {
+                    @unlink($tempFile['path']);
+                }
                 
                 $elapsed = round(microtime(true) - $startTime, 2);
                 dLog('generate')->info('cURL请求完成', ['elapsed' => $elapsed . 's', 'http_code' => $statusCode, 'curl_errno' => $curlErrno]);