fbpx
How to Upload Image to Imgur in Android using Kotlin

How to Upload Image to Imgur in Android using Kotlin

Today, I will show you how to upload an image anonymously from your phone’s photo library to imgur.com

On my demo app, at the end of this article, the user first chooses an image from the Photos app and then uploads it to imgur.com.

This tutorial only focuses on how to upload an image to imgur, not choosing an image from your phone.

As an example, we are going to upload the following image I found on the Internet 🐶

Getting the Client ID

As I said before, we’re going to upload an image anonymously, but imgur still wants to know from which app they’re coming from.

For that, we need to get a Client ID from their website.

Go to https://api.imgur.com/oauth2/addclient and create an imgur account, if you haven’t already.

Fill the required fields and press submit

Copy the Client ID somewhere. We’re gonna need it later.

Imgur has some limitations on how many uploads can get from a single app every day (approx. 1,250 uploads per day). You can read more about that here.

Let’s get started!!

First, we need to add Coroutines to our project. This will help us convert the Bitmap image to Base64 and upload it in the background thread without freezing the UI.

You can use AsyncTask instead, but Coroutines makes the job a lot easier.

Go to the build.gradle of your app and add the following dependency:

dependencies {
    // ...
   
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5'
    
    // ...
}

Next, go to your AndroidManifest.xml (manifests > AndroidManifest.xml) and add the following permission to be able to upload the image on the internet:

<uses-permission android:name="android.permission.INTERNET" />

Creating the Image Uploader

Let’s create a method uploadImageToImgur that takes a Bitmap as a parameter.

private fun uploadImageToImgur(image: Bitmap) {
        // ...
}

Convert the image (Bitmap) to Base64 text.

private fun uploadImageToImgur(image: Bitmap) {
        getBase64Image(image, complete = { base64Image ->
            // ...
        })
    }

    private fun getBase64Image(image: Bitmap, complete: (String) -> Unit) {
        GlobalScope.launch {
            val outputStream = ByteArrayOutputStream()
            image.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
            val b = outputStream.toByteArray()
            complete(Base64.encodeToString(b, Base64.DEFAULT))
        }
    }

Make an HTTP POST request to https://api.imgur.com/3/image that takes as HTTP Header the Client ID we got before.

private val CLIENT_ID = "MY_CLIENT_ID"

private fun uploadImageToImgur(image: Bitmap) {
        getBase64Image(image, complete = { base64Image ->
            GlobalScope.launch(Dispatchers.Default) {
                val url = URL("https://api.imgur.com/3/image")

                val boundary = "Boundary-${System.currentTimeMillis()}"

                val httpsURLConnection =
                    withContext(Dispatchers.IO) { url.openConnection() as HttpsURLConnection }
                httpsURLConnection.setRequestProperty("Authorization", "Client-ID $CLIENT_ID")
                httpsURLConnection.setRequestProperty(
                    "Content-Type",
                    "multipart/form-data; boundary=$boundary"
                )

                httpsURLConnection.requestMethod = "POST"
                httpsURLConnection.doInput = true
                httpsURLConnection.doOutput = true

                var body = ""
                body += "--$boundary\r\n"
                body += "Content-Disposition:form-data; name=\"image\""
                body += "\r\n\r\n$base64Image\r\n"
                body += "--$boundary--\r\n"


                val outputStreamWriter = OutputStreamWriter(httpsURLConnection.outputStream)
                withContext(Dispatchers.IO) {
                    outputStreamWriter.write(body)
                    outputStreamWriter.flush()
                }
                
                
                // ...
              
            }
        })
    }

This is how the JSON data looks like as a result after uploading successfully your image:

{
   "data":{
      "id":"EBJIeoZ",
      "title":null,
      "description":null,
      "datetime":1582389917,
      "type":"image/jpeg",
      "animated":false,
      "width":1667,
      "height":2048,
      "size":172036,
      "views":0,
      "bandwidth":0,
      "vote":null,
      "favorite":false,
      "nsfw":null,
      "section":null,
      "account_url":null,
      "account_id":0,
      "is_ad":false,
      "in_most_viral":false,
      "has_sound":false,
      "tags":[

      ],
      "ad_type":0,
      "ad_url":"",
      "edited":"0",
      "in_gallery":false,
      "deletehash":"aCbT2JmYe6JYJp1",
      "name":"",
      "link":"https://i.imgur.com/EBJIeoZ.jpg"
   },
   "success":true,
   "status":200
}

Parse the JSON data and get the link.

private fun uploadImageToImgur(image: Bitmap) {
        getBase64Image(image, complete = { base64Image ->
            GlobalScope.launch(Dispatchers.Default) {
                 
                // ...
              
              
                val response = httpsURLConnection.inputStream.bufferedReader()
                    .use { it.readText() }  // defaults to UTF-8
                val jsonObject = JSONTokener(response).nextValue() as JSONObject
                val data = jsonObject.getJSONObject("data")
                
                Log.d("TAG", "Link is : ${data.getString("link")}")
               
            }
        })
    }

Using the Image Uploader

In your Activity‘s file, use the method we made before by calling the uploadImageToImgur and passing the image (Bitmap) you want to upload.

upload_image.setOnClickListener {
      uploadImageToImgur(selectedImage)
}
You can find the final project here

If you have any questionsplease feel free to leave a comment below

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments