Android使用Retrofit Multipart上传BMP头像到服务器提示非有效图像错误
问题原因及修复方案
你遇到的服务端报错是由以下几个错误共同导致的:
- 上传的文件名未携带对应格式后缀:你调用
MultipartBody.Part.createFormData时传入的文件名是avatar,没有带上.jpg后缀,多数服务端会通过文件名后缀校验文件格式,无合法后缀会直接判定为无效文件。 - MediaType声明不明确:你设置的MediaType是通用的
image/*,严格的服务端会校验MediaType和实际文件格式是否匹配,泛型声明会被拦截。 - 冗余代码隐患:你在Android 9及以上版本的逻辑中连续调用了两次
ImageDecoder.decodeBitmap(source),属于多余操作,虽然不会直接导致上传失败,但会造成不必要的性能损耗。
修复后的bitmapToMultipart代码
fun bitmapToMultipart(imageBitmap: Bitmap): MultipartBody.Part { val bos = ByteArrayOutputStream() // 确认压缩格式和后续声明的MediaType、文件名后缀一致 imageBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos) val bitmapdata = bos.toByteArray() Log.i(TAG, "bitmapToMultipart: ${Base64.encodeToString(bitmapdata,Base64.NO_WRAP)}") // 明确指定MediaType为image/jpeg,和压缩格式匹配 val requestBody = bitmapdata.toRequestBody("image/jpeg".toMediaTypeOrNull()) // 文件名带上.jpg后缀,匹配文件格式 return MultipartBody.Part.createFormData("file", "avatar.jpg", requestBody) }
可选优化(选图冗余代码修复)
把UploadButton里重复的decode代码删掉,只保留一次即可:
} else { val source = ImageDecoder .createSource(context.contentResolver, it) // 删掉重复的decode调用,只保留一次 bitmapSelected.value = ImageDecoder.decodeBitmap(source) }
如果你确实需要上传BMP格式文件,注意Android原生Bitmap.compress方法不支持BMP编码,你需要自行实现BMP编码逻辑,或者和服务端协商使用JPEG/PNG这类Android原生支持的压缩格式即可。
内容的提问来源于stack exchange,提问作者Beesz
相关产品推荐
相关产品推荐

