You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中图片Uri转Bitmap再编码为Base64及异常解决求助

Kotlin中从Content Uri转Bitmap并编码为Base64的正确方法

你遇到的FileNotFoundException是因为content://开头的Uri并不是直接的本地文件路径,它是Android内容提供者(Content Provider)的Uri,不能直接用File(uri.path)来访问文件。得通过ContentResolver来获取文件的输入流,这才是处理这类Uri的正确方式。

下面是完整的实现流程和代码:

步骤说明

  1. 通过ContentResolver打开Uri对应的输入流
  2. 将输入流转为Bitmap对象
  3. 将Bitmap压缩为字节数组,再编码成Base64字符串

完整Kotlin代码

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.util.Base64
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.io.InputStream

fun uriToBase64(context: Context, uri: Uri): String? {
    var inputStream: InputStream? = null
    var bitmap: Bitmap? = null
    return try {
        // 1. 通过ContentResolver获取输入流
        inputStream = context.contentResolver.openInputStream(uri)
        // 2. 将输入流转为Bitmap
        bitmap = BitmapFactory.decodeStream(inputStream)
        // 3. 压缩Bitmap为字节数组并编码为Base64
        ByteArrayOutputStream().use { outputStream ->
            // 这里可以调整压缩格式和质量,比如PNG质量是100,JPEG可以设为80-90
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream)
            val byteArray = outputStream.toByteArray()
            Base64.encodeToString(byteArray, Base64.DEFAULT)
        }
    } catch (e: IOException) {
        e.printStackTrace()
        null // 处理异常,返回null或者根据需求抛出
    } finally {
        // 关闭资源
        inputStream?.close()
        bitmap?.recycle() // 回收Bitmap内存,避免OOM
    }
}

使用示例

从数据库取出Uri字符串后,这样调用即可:

val uriString = "content://media/external/images/media/109"
val uri = Uri.parse(uriString)
val base64String = uriToBase64(applicationContext, uri)

// 之后就可以把base64String和其他数据一起通过POST请求发送给API了

额外注意事项

  • 权限问题:如果是访问外部存储的图片,Android 10及以上可以借助Scoped Storage无需申请READ_EXTERNAL_STORAGE权限;但低于Android 10的版本,需要确保App已经获取到该权限。
  • Bitmap内存优化:如果图片尺寸很大,直接转Bitmap可能会触发OOM,可以通过BitmapFactory.Options设置采样率缩小图片:
val options = BitmapFactory.Options()
options.inSampleSize = 2 // 缩小为原来的1/2,可根据需求调整数值
bitmap = BitmapFactory.decodeStream(inputStream, null, options)
  • 压缩格式选择:需要透明背景选Bitmap.CompressFormat.PNG;追求更小体积选JPEG格式即可。

内容的提问来源于stack exchange,提问作者luisfer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:53:38