androidretrofit

How to POST a bitmap to a server using Retrofit/Android


I'm trying to post a bitmap to a server using Android and Retrofit.

Currently I know how to post a file, but I'd prefer to send a bitmap directly.

This is because the user can pick any image off their device. I'd like to resize it to save bandwidth before it gets sent to the server and preferrably not have to load it, resize it, save it as a file to local storage then post the file.

Anyone know how to post a bitmap from Retrofit?


Solution

  • NOTE: Make this conversion on other thread than Main. RxJava could help to achieve this, or Coroutines

    First convert your bitmap to file

    //create a file to write bitmap data
    File f = new File(context.getCacheDir(), filename);
    f.createNewFile();
    
    //Convert bitmap to byte array
    Bitmap bitmap = your bitmap;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(CompressFormat.JPEG, 0 /*ignored for PNG*/, bos);
    byte[] bitmapdata = bos.toByteArray();
    
    //write the bytes in file
    FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            fos.write(bitmapdata);
            fos.flush();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    

    After that create a request with Multipart in order to upload your file

    RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), f);
    MultipartBody.Part body = MultipartBody.Part.createFormData("upload", f.getName(), reqFile);
    

    Your service call should look like this

    interface Service {
        @Multipart
        @POST("/yourEndPoint")
        Call<ResponseBody> postImage(@Part MultipartBody.Part image);
    }
    

    And then just call your api

    Service service = new Retrofit.Builder().baseUrl("yourBaseUrl").build().create(Service.class);
    Call<okhttp3.ResponseBody> req = service.postImage(body);
    req.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { 
             // Do Something with response
        }
    
        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            //failure message
            t.printStackTrace();
        }
    });