Kotlin开发Android应用实现拍照并本地存储1-3张图片方案咨询
注意:SharedPreferences 本质是XML键值对存储,仅适合存储小体积数据。Base64编码会让图片体积比原二进制大1/3左右,建议你先将拍摄的图片压缩到单张1MB以内再存入,避免出现读写卡顿、ANR等问题。如果你的业务场景图片体积较大,更推荐你将图片存入App专属内部缓存目录,仅在SP中存储图片的本地路径即可,以下是你需要的SP直接存储图片的实现方案。
实现原理
因为 SharedPreferences 仅支持存储基础类型和字符串,所以需要先将图片 Bitmap 压缩后编码为 Base64 字符串,再存入SP,读取时再将Base64字符串解码转回Bitmap即可。
具体实现步骤
1. 编写图片转码工具方法
import android.graphics.Bitmap import android.graphics.BitmapFactory import android.util.Base64 import java.io.ByteArrayOutputStream // Bitmap 转 Base64 字符串 fun bitmapToBase64(bitmap: Bitmap, quality: Int = 80): String { val outputStream = ByteArrayOutputStream() // 先压缩为JPEG,quality取值0-100,数值越高质量越好、体积越大 bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream) val byteArray = outputStream.toByteArray() outputStream.close() return Base64.encodeToString(byteArray, Base64.DEFAULT) } // Base64 字符串转回 Bitmap fun base64ToBitmap(base64Str: String): Bitmap? { return if (base64Str.isEmpty()) { null } else { val byteArray = Base64.decode(base64Str, Base64.DEFAULT) BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size) } }
2. 存储图片到SharedPreferences
因为你最多存3张图,可以按序号分别存储,同时存入过期时间实现临时存储的自动失效逻辑:
import android.content.Context import android.content.SharedPreferences // 初始化SP,指定私有模式,仅本App可访问 val tempImageSp: SharedPreferences = context.getSharedPreferences("temp_image_sp", Context.MODE_PRIVATE) // 存储逻辑示例 fun saveTempImages(img1: Bitmap?, img2: Bitmap?, img3: Bitmap?, validHours: Int = 24) { val editor = tempImageSp.edit() // 存储图片,空图存空字符串 editor.putString("img_1", img1?.let { bitmapToBase64(it) } ?: "") editor.putString("img_2", img2?.let { bitmapToBase64(it) } ?: "") editor.putString("img_3", img3?.let { bitmapToBase64(it) } ?: "") // 存储过期时间,默认24小时后失效 editor.putLong("expire_timestamp", System.currentTimeMillis() + validHours * 60 * 60 * 1000) editor.apply() }
3. 读取存储的图片
读取时先判断是否过期,过期直接清空存储的旧数据:
fun getTempImages(): List<Bitmap?> { // 先判断是否过期 val expireTime = tempImageSp.getLong("expire_timestamp", 0) if (System.currentTimeMillis() > expireTime) { // 过期清空所有数据 tempImageSp.edit().clear().apply() return emptyList() } // 读取图片并转回Bitmap val img1 = base64ToBitmap(tempImageSp.getString("img_1", "") ?: "") val img2 = base64ToBitmap(tempImageSp.getString("img_2", "") ?: "") val img3 = base64ToBitmap(tempImageSp.getString("img_3", "") ?: "") return listOfNotNull(img1, img2, img3) }
优化建议
- 存入前先对图片做分辨率压缩,比如将拍摄的高分辨率原图缩小到业务需要的尺寸(如1080p),能大幅降低最终存储的体积
- 每次App启动时可以自动执行一次过期校验,清理过期的图片数据,避免SP文件体积持续膨胀
- 如果后续需要存储更多图片,建议直接将图片文件存在App的私有缓存目录
context.cacheDir下,仅在SP中存储对应文件的路径,读写性能会高很多
内容的提问来源于stack exchange,提问作者Da Ro
相关产品推荐
相关产品推荐

