Kotlin Fragment场景下如何将Bitmap转换为MultipartBody.Part?
问题根因
你现在报类型不匹配的核心原因是:直接把cameraResult这个ActivityResultLauncher启动器对象传给了上传接口,既没有在相机回调里把拿到的Bitmap做类型转换,也没有取到实际的图片数据传参,自然和接口要求的MultipartBody.Part类型对不上。
Bitmap转MultipartBody.Part实现步骤
- 拿到相机回调返回的Bitmap对象后,先将其压缩写入字节输出流,可根据需求选择图片格式、压缩质量,头像场景一般选JPEG格式、70-90的压缩质量即可平衡文件大小和清晰度
- 基于压缩后的字节数组创建RequestBody,指定对应的MIME类型为图片类型
- 调用OkHttp提供的
MultipartBody.Part.createFormData方法,传入接口约定的表单字段名、自定义文件名、上一步生成的RequestBody,就能得到接口需要的参数对象
适配后的完整代码
// 依赖提前导入,Retrofit+OkHttp3组合不需要额外引包 import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.ByteArrayOutputStream private val cameraResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK && result.data != null) { val bitmap = result.data?.extras?.get("data") as Bitmap binding.ivProfile.loadImage(bitmap) // 执行Bitmap转MultipartBody逻辑 val baos = ByteArrayOutputStream() // 压缩参数:图片格式、压缩质量0-100、输出流 bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos) // 生成RequestBody val imageRequestBody = baos.toByteArray() .toRequestBody("image/jpeg".toMediaTypeOrNull()) // 生成接口需要的MultipartBody.Part,第一个参数替换成你后端要求的表单字段名,常见值为"avatar"/"file" val avatarPart = MultipartBody.Part.createFormData( "avatar", "avatar_${System.currentTimeMillis()}.jpg", imageRequestBody ) // 后续在这里调用上传接口,传入avatarPart即可,禁止传cameraResult对象 // 示例:api.uploadAvatar(avatarPart) // 资源回收避免内存泄漏 baos.close() bitmap.recycle() } }
注意事项
- 你现在通过
extras.get("data")拿到的是相机返回的缩略图,如果需要高清头像,不要用这种方式,要提前配置相机输出到指定本地文件,再基于文件生成MultipartBody,避免图片模糊 createFormData的第一个表单字段名必须和后端约定完全一致,否则后端无法识别接收参数- 压缩、流操作如果处理的是大图,建议切到IO线程执行,不要在主线程做耗时操作避免ANR
内容的提问来源于stack exchange,提问作者uul
相关产品推荐
相关产品推荐

