Kotlin开发Android应用调用OpenAI图像编辑API遇415错误求助
解决OpenAI Images Edits接口415错误及图像传输问题
你的415错误核心原因是:OpenAI的v1/images/edits接口要求使用**multipart/form-data**格式传输请求(因为包含文件),而你当前用@Body传递JSON格式请求体,服务器不支持该媒体类型,因此返回415响应。
以下是直接可落地的修复方案:
1. 修改Retrofit接口定义
将接口改为多部分表单请求,用@Multipart和@Part分别传递文件和参数:
import okhttp3.MultipartBody import okhttp3.RequestBody import retrofit2.http.Multipart import retrofit2.http.POST import retrofit2.http.Header import retrofit2.http.Part interface OpenAI { @Multipart @POST("/v1/images/edits") suspend fun sendImageEditRequest( @Header("Authorization") apiKey: String, @Part image: MultipartBody.Part, @Part("prompt") prompt: RequestBody, // 可选参数:按需添加,比如生成数量、图片尺寸 @Part("n") n: RequestBody? = null, @Part("size") size: RequestBody? = null ): EditResponse }
2. 调整ViewModel中的请求逻辑
需要将相机拍摄的图片Uri转换为MultipartBody.Part,并构建正确的请求体:
import okhttp3.MediaType.Companion.toMediaType import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import android.content.ContentResolver import android.net.Uri import android.provider.MediaStore import kotlinx.coroutines.launch fun editImage() { val retrofit = Retrofit.Builder() .baseUrl("https://api.openai.com") .addConverterFactory(MoshiConverterFactory.create()) .build() val openAi = retrofit.create(OpenAI::class.java) val promptText = "A giant mice with a hat" imgUri.value?.let { uri -> // 1. 将Uri转换为RequestBody(适配Android全版本) val contentResolver: ContentResolver = context.contentResolver val imageInputStream = contentResolver.openInputStream(uri) val imageRequestBody = imageInputStream?.use { it.readBytes().asRequestBody("image/jpeg".toMediaType()) } ?: return // 2. 构建文件Part val imagePart = MultipartBody.Part.createFormData( name = "image", filename = "edit_image.jpg", // 文件名可自定义 body = imageRequestBody ) // 3. 构建prompt参数 val promptRequestBody = promptText.toRequestBody("text/plain".toMediaType()) viewModelScope.launch { try { // 注意API Key要带Bearer前缀 val response = openAi.sendImageEditRequest( "Bearer $API_KEY", imagePart, promptRequestBody ) Log.i("URL", response.data.first().url) // 假设EditResponse包含data列表 } catch (e: Exception) { Log.e("Exception", e.toString()) } } } }
3. 关键注意事项
- 权限处理:Android 10及以下需申请
READ_EXTERNAL_STORAGE权限;Android 11+无需申请,但需通过ContentResolver访问文件,避免直接读取路径。 - MIME类型匹配:确保
image/jpeg或image/png与实际图片格式一致,否则可能引发服务器报错。 - API Key格式:必须以
Bearer开头,比如Bearer sk-xxxxxx。
内容的提问来源于stack exchange,提问作者Decodator
相关产品推荐
相关产品推荐

