You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 01:45:03