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?
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.