[Android/Kotlin] 비트맵으로 이미지 넘기기

코코아의 개발일지·2023년 10월 12일
0

Android-Kotlin

목록 보기
13/31

✍🏻 요구 사항 분석


프래그먼트 전환을 할 때, 클릭한 앨범 정보를 다른 프래그먼트로 넘겨서 보여줘야 했다.
사진까지 넘겨주고 싶었는데, 어떤 사진이 있을지 모르니까 리소스를 넘겨주는 것보다는 이미지뷰의 이미지를 직접 넘겨주는 방법을 찾아보게 됐다.

💻 코드 작성

1️⃣ 텍스트, 이미지 넘기기 (HomeFragment.kt)

// 앨범 클릭 시 정보 넘기기
private fun moveToAlbumFragment() {
        val albumFragment = AlbumFragment()

        val bundle = Bundle()

        // 이미지뷰의 이미지를 비트맵으로 변환
        val bitmap = (binding.homeAlbum1CoverIv.drawable as BitmapDrawable).bitmap

        // 비트맵을 ByteArray로 직렬화
        val byteArrayOutputStream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream)
        val byteArray = byteArrayOutputStream.toByteArray()

        // bundle에 데이터 담기
        bundle.putByteArray("img", byteArray)
        bundle.putString("title", binding.homeAlbum1TitleTv.text.toString())
        bundle.putString("singer", binding.homeAlbum1SingerTv.text.toString())
        // albumFragment의 arguments에 데이터를 담은 bundle을 넘겨줌
        albumFragment.arguments = bundle

        (context as MainActivity).supportFragmentManager.beginTransaction().replace(R.id.main_frm, albumFragment).commitAllowingStateLoss()
    }

2️⃣ 텍스트, 이미지 받아서 뷰 랜더링하기 (AlbumFragment.kt)

private fun receiveHomeData() {
        // 번들로부터 ByteArray 받아오기
        val byteArray = arguments?.getByteArray("img")

        if (byteArray != null) {
            // ByteArray를 Bitmap으로 변환
            val bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)

            // 앨범 커버 이미지에 Bitmap 설정
            binding.albumCoverImgIv.setImageBitmap(bitmap)
        }
        // 앨범 제목, 가수 설정
        binding.albumTitleTv.text = arguments?.getString("title")
        binding.albumSingerTv.text = arguments?.getString("singer")
    }

🤔 생각해보기

어쨌든 성공은 했고, 나는 이미지 리소스를 직접 넘기는 게 아니라 ImageView의 이미지 자체를 넘기고 싶었던 거라 이미지를 번들에 byteArray 형태로 넘기는 게 최선이었다고 생각함. 하지만 ImageView에 설정된 이미지 자체를 번들로 직접 넘기는 것은 용량으로 인한 성능 저하의 우려 때문에 권장되지 않는다고 한다.
내가 쓴 방법 말고도, 번들로 이미지의 식별자나 경로 등을 넘기고, 필요한 경우 받는 측에서 해당 식별자나 경로를 사용하여 이미지를 설정하는 방법이 있다.

drawable id로 넘기는 방법

  • 보내는 쪽 (HomeFragment.kt)
    bundle.putInt("img", R.drawable.img_album_exp2)
  • 받는 쪽 (AlbumFragment.kt)
    arguments?.getInt("img")?.let { binding.albumCoverImgIv.setImageResource(it) }

코드가 훨씬 더 간단하지만, 리소스를 지정해서 넘겨줘야한다.
그렇지만 생각해보니 코틀린 파일에서 데이터에 직접 리소스를 넣어주는 경우라면 그 데이터에 들어간 리소스를 넘겨줘도 될 듯..? (어차피 서버에서 받아오는 순간 url을 넘겨주겠지만..) 순간 뭔가 잘못 생각해서 삽질했던 거 같은데 어쨌든 지식 +1이 된 것에 만족한다.

📚 참고 자료

profile
우당탕탕 성장하는 개발자

0개의 댓글