首页 > 解决方案 > 如何使用 MediaColumns#IS_PENDING 将位图转换为 Uri?

问题描述

我正在使用以下代码将位图转换为 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)
}

这段代码工作正常。但是,将 sdk 版本更新到 29 后, insertImage不推荐使用方法。当我检查文档时,我看到了这个声明:

此方法在 API 级别 29 中已弃用。应使用 MediaColumns#IS_PENDING 执行图像的插入,它提供了对生命周期的更丰富的控制。

那么,如何使用这个将位图转换为 UriMediaColumns#IS_PENDING呢?

标签: androidkotlinmediastore

解决方案


试试下面的片段:

此方法可以帮助您从位图中获取 Uri,而不会消耗一些额外的内存。

 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
}

推荐阅读