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

如何通过Retrofit上传Bitmap?已完成图片选取与缩放

我来帮你把这个流程拆解清楚,结合你已经完成的图片加载和缩放操作,下面是一步一步的具体实现方案,都是经过验证的常规做法:

1. 先确认依赖配置

首先确保你的项目Gradle里已经添加了Retrofit及相关依赖(如果还没加的话):

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0' // 可选,用来调试请求日志
2. 定义Retrofit上传接口

根据你的接口要求,定义对应的API接口类,注意@Multipart和@Accept注解的使用:

import okhttp3.MultipartBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Accept;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;

public interface FileUploadApi {
    @Multipart
    @POST("/api/file")
    @Accept("application/json") // 指定请求头的Accept字段
    Call<ResponseBody> uploadScaledImage(
        @Part MultipartBody.Part imageFilePart
    );
}

这里@Multipart注解会自动帮你设置Content-Type: multipart/form-data,不用手动配置。

3. 把Bitmap转成RequestBody(核心步骤)

因为Retrofit上传文件需要用RequestBody封装,所以我们需要把你已经缩放好的Bitmap转换成字节流,再封装成请求体:

import android.graphics.Bitmap;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import java.io.ByteArrayOutputStream;

// 工具方法:将Bitmap转为RequestBody
private RequestBody convertBitmapToRequestBody(Bitmap scaledBitmap) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // 可根据需求调整压缩格式和质量,透明图用PNG,普通图用JPEG更省空间
    scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
    byte[] imageBytes = baos.toByteArray();
    // 指定媒体类型,要和服务端预期的文件类型匹配
    return RequestBody.create(MediaType.parse("image/jpeg"), imageBytes);
}
4. 执行上传请求

接下来就是创建Retrofit实例、构建请求并发起异步上传:

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

// 1. 初始化Retrofit实例(记得替换成你的服务器基础URL)
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://your-server-domain.com")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

// 2. 获取API接口实例
FileUploadApi uploadApi = retrofit.create(FileUploadApi.class);

// 3. 处理你的缩放后的Bitmap(这里直接用你已经准备好的对象即可)
Bitmap yourScaledBitmap = 你的缩放后Bitmap实例;
RequestBody imageRequestBody = convertBitmapToRequestBody(yourScaledBitmap);

// 4. 构建MultipartBody.Part,注意第一个参数是服务端接收文件的参数名,要和后端约定好
MultipartBody.Part imagePart = MultipartBody.Part.createFormData(
    "file", // 比如后端用@RequestParam("file")来接收这个文件
    "uploaded_image.jpg", // 自定义文件名,可随意设置
    imageRequestBody
);

// 5. 发起异步上传请求
Call<ResponseBody> uploadCall = uploadApi.uploadScaledImage(imagePart);
uploadCall.enqueue(new retrofit2.Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
        if (response.isSuccessful()) {
            // 上传成功,处理服务端返回的JSON响应
            try {
                String responseContent = response.body().string();
                // 这里可以解析返回的JSON数据
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            // 上传失败,处理错误信息
            try {
                String errorMsg = response.errorBody().string();
                // 解析错误内容
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // 网络请求失败,处理异常(比如无网络、超时等)
        t.printStackTrace();
    }
});
几个关键注意点
  • 服务端接收文件的参数名(代码里的"file")一定要和后端开发人员约定好,不然服务端拿不到文件。
  • 如果需要上传额外的表单字段,可以在uploadScaledImage方法里添加@Part("param_name") RequestBody param这样的参数。
  • 建议开启OkHttp的日志拦截器,方便调试时查看请求头、参数是否符合要求。
  • 所有网络操作都要在子线程执行,Retrofit的enqueue方法已经帮我们处理了后台线程,不需要自己额外开线程。

内容的提问来源于stack exchange,提问作者CoolMind

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:31:32