0

I am using the following code to convert bitmap to Uri:

fun convertBitmapToUri(context: Context, bitmap: Bitmap): Uri {
    val bytes = ByteArrayOutputStream()
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes)
    val path = MediaStore.Images.Media.insertImage(context.contentResolver, bitmap, "Title", null)
    return Uri.parse(path)
}

This code works fine. But, after updating the sdk version to 29, insertImage method is deprecated. And when I checked the doc, I saw this statement:

This method was deprecated in API level 29. inserting of images should be performed using MediaColumns#IS_PENDING, which offers richer control over lifecycle.

So, how can I convert bitmap to Uri using this MediaColumns#IS_PENDING?

Son Truong
  • 13,661
  • 5
  • 32
  • 58
eegooDeveloper
  • 395
  • 5
  • 12
  • Does this answer your question? [MediaStore.Images.Media.insertImage deprecated](https://stackoverflow.com/questions/57726896/mediastore-images-media-insertimage-deprecated) – Son Truong Jan 09 '20 at 07:41
  • One cannot convert a bitmap to an uri. – blackapps Jan 09 '20 at 08:30

2 Answers2

0

Try below snippet:

This method may help you to get the Uri from bitmap without consuming some extra memory.

 private fun convertToUri(mBitmap: Bitmap): Uri? {
    var uri: Uri? = null
    try {
        val options: BitmapFactory.Options = BitmapFactory.Options()
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, 100, 100)

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false
        val newBitmap = Bitmap.createScaledBitmap(
            mBitmap, 200, 200,
            true
        )
        val file = File(
            this.filesDir, "Image"
                    + Random().nextInt() + ".jpeg"
        )
        val out = this.openFileOutput(
            file.name,
            Context.MODE_WORLD_READABLE
        )
        newBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)
        out.flush()
        out.close()
        //get absolute path
        val realPath = file.absolutePath
        val f = File(realPath)
        uri = Uri.fromFile(f)

    } catch (e: Exception) {

    }
    return uri
}

fun calculateInSampleSize(
    options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int
): Int {
    // Raw height and width of image
    val height = options.outHeight
    val width = options.outWidth
    var inSampleSize = 1

    if (height > reqHeight || width > reqWidth) {

        val halfHeight = height / 2
        val halfWidth = width / 2

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) >= reqHeight
            && (halfWidth / inSampleSize) >= reqWidth
        ) {
            inSampleSize *= 2
        }
    }

    return inSampleSize
}
Kalpesh Rupani
  • 991
  • 4
  • 12
0

Here is your code to get bimpa to URI

private fun saveImage(myBitmap : Bitmap) : String {

    val bytes = ByteArrayOutputStream()
    myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes)

    val folder = File(Environment.getExternalStorageDirectory().absolutePath + "/" + ".yourFolder")
    // have the object build the directory structure, if needed.
    if (!folder .exists()) {
        folder .mkdirs()
    }

    try {
        val f = File(folder , "image_name.jpg")
        f.createNewFile()
        val fo = FileOutputStream(f)
        fo.write(bytes.toByteArray())
        MediaScannerConnection.scanFile(this, arrayOf(f.path), arrayOf("image/*"), { path, uri -> 
            val _uri = uri // Here is your URI from bitmap
            val _path = path // In case if you want path of that bitmp in storage
        })
        fo.close()

        return f.absolutePath
    } catch (e1 : IOException) {
        e1.printStackTrace()
    }

    return ""
}