Kotlin

[Kotlin] Storage 이미지 저장, 불러오기, 삭제

eulBlue 2023. 12. 19. 18:34

📱테스트 환경

Samsung Galaxy Android 13 • Android 10


무지렁이 시절 이미지를 저장하고 싶은데, 이미지를 Room 에 저장하고 싶었다. 근데 Bitmap 형식은 Room 에 저장이 안되더라 .. ?

그래서 무지렁이인 나는 Bitmap 을 ByteArray 로 변환해서 Room 에 저장했다 ㅋㅋ

당연히 메모리도 무지막지하게 잡아먹었고 .. 나같이 하는 사람도 없으니 에러가 발생해도 해결하기도 어렵더라 ..

그러다가 멘토님께 설명을 들였는데 당연히 당황하셨고 ㅎ .. 스토리지에 이미지를 저장해놓고, 키값을 Room 에 저장해놓고 그걸로 불러다가 사용하는 거라고 친절하게 설명해주셨다.

해서 이 방법을 기록해 두려고 한다.

fun saveImageToInternalStorage(context: Context, bitmap: Bitmap?): String? {
    if(bitmap == null) {
        return null
    }
    val directory = context.filesDir
    val imageKey = UUID.randomUUID().toString()
    val filePath = "$directory/$imageKey.png"

    try {
        val stream = FileOutputStream(filePath)
        bitmap.compress(Bitmap.CompressFormat.PNG, 80, stream)
        stream.close()
    } catch (e: IOException) {
        e.printStackTrace()
    }
    return imageKey
}

Bitmap 과 Context 를 받아와서 files 폴더에 저장하는 구조이다.

처음에는 용량생각에 JPEG 로 저장을 하려고 했더니 이미지 뒤에 검정색 배경이 생기더라 ..?

당연하게도 JPEG 는 투명색을 지원 안한다 ㅎ 그래서 투명색 부분을 검정색으로 채우는 기본적인것도 까먹고 용량만 생각하다가

삽질좀 하다가 ? PNG 로 변경해서 깔끔하게 해결 !

나는 그냥 UUID 랜덤으로 파일명을 저장하였다.

저장된 파일은 Device File Explorer > data > data > [패키지명 ] > files 에 보면 확인할 수 있다.

이제 추가로 Room 에서 데이터를 지우면 스토리지에 저장한 이미지도 저장해야한다.

안그러면 더미데이터마냥 계속 쌓일테고 .. 앱은 용량을 무지막지하게 잡아먹을테니까 ..

fun deleteImageFromInternalStorage(context: Context, imageKey: String?): Boolean {
    if (imageKey == null) {
        return false
    }

    val directory = context.filesDir
    val filePath = "$directory/$imageKey.png"
    val file = File(filePath)

    return if (file.exists()) {
        file.delete()
    } else {
        false
    }
}

Room 에서 데이터를 지우기 전에 Key 값을 먼저 가져와서

함수에 Context 와 Key 값을 넣어주고 파일에 저장된 이미지를 삭제해주면 된다.

불러오는 방식은 다른 이미지들을 불러오는것처럼 아주 간단하게 불러올 수 있다.

val imageKey = chattingList[position].image
glideRequestManager
    .load("${context.filesDir}/$imageKey.png")
    .into(holder.image)