Search code examples
androidimagekotlinbase64filenotfoundexception

File not found exception while encoding image from path


I want to convert an image file to base64. I am requesting the image by starting an Activity with intent as follows

val intent = Intent(
        Intent.ACTION_PICK,
        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI
    )
intent.type = "image/*"

On the onActivityResult I am trying to get the real path the Uri received as a result. One approach I followed is below

 fun getRealPathFromUri(context: Context, contentUri: Uri?): String {
            val result: String
            val cursor: Cursor = contentUri?.let { context.contentResolver.query(it, null, null, null, null) }!!
            cursor.moveToFirst()
            val idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
            result = cursor.getString(idx)
            cursor.close()
            return result
        
       }

With the above approach, I get real path as

storage/emulated/0/DICM/myImagepath

is this correct?

I also tried adding file:// before the path, but it is also not working.

Other approaches I tried are

fun getPath(context: Context, uri: Uri?): String? {
     try {
        var cursor = context.contentResolver.query(uri!!, null, null, null, null)
        cursor!!.moveToFirst()
        var document_id = cursor.getString(0)
        document_id = document_id.substring(document_id.lastIndexOf(":") + 1)
        cursor.close()
        cursor = context.contentResolver.query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            null, MediaStore.Images.Media._ID + " = ? ", arrayOf(document_id), null
        )
        cursor!!.moveToFirst()
        val path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
        cursor.close()
        return path
    } catch (e: Exception) {
        e.printStackTrace()
        return null
    }
}

But this does not generate the document_id and does not give the real path, as there's possibly some problem in my code.

After getting the real path I tried two solutions to convert image to base64

Solution1

fun convertToBase64(imageUrl: String): String{

    val imagefile = File(imageUrl)
    var fis: FileInputStream? = null
    try {
        fis = FileInputStream(imagefile)
    } catch (e: FileNotFoundException) {
        e.printStackTrace()
    }
    val bm = BitmapFactory.decodeStream(fis)
    val baos = ByteArrayOutputStream()
    bm.compress(Bitmap.CompressFormat.JPEG, 100, baos)
    val b: ByteArray = baos.toByteArray()

    return encodeToString(b, Base64.DEFAULT)

}

solution2

fun encodeBitmapToBase64String(
    image: Bitmap?,
    compressFormat: CompressFormat?,
    quality: Int
): String? {
    val byteArrayOS = ByteArrayOutputStream()
    image?.compress(compressFormat, quality, byteArrayOS)
    return encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT)
}

Solution 1 throws FilenotFoundexception, as per my understanding it is because it does not find the real path.

Solution 2 returns null for the same reason I guess.

I found the above approaches from several best solutions of stack overflow answers, but it does not work for me.

I actually do not understand why my file path was wrong, or the convertion technique to base64.

What is the solution for this?


Solution

  •   fun convertToBase64(imageUri: Uri):
    
     var is: InputStream  
    
      is = contentresolver.openinputstream(imageUri)
    

    Use is like fis.

    Call with;

    ... = convertToBase64(data.data)
    

    Or is it data.string?

    Dont mess around with functions like get real parh from uri. Throw them away.