Kotlin中图片Uri转Bitmap再编码为Base64及异常解决求助
Kotlin中从Content Uri转Bitmap并编码为Base64的正确方法
你遇到的FileNotFoundException是因为content://开头的Uri并不是直接的本地文件路径,它是Android内容提供者(Content Provider)的Uri,不能直接用File(uri.path)来访问文件。得通过ContentResolver来获取文件的输入流,这才是处理这类Uri的正确方式。
下面是完整的实现流程和代码:
步骤说明
- 通过
ContentResolver打开Uri对应的输入流 - 将输入流转为
Bitmap对象 - 将
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
相关产品推荐
相关产品推荐

