Quest: 갤러리에서 가져온 picture 를 가져와서 해당 uri 를 bitmap 으로 변환시켜야한다.
Issue: bitmap 으로 변환해서 표시하니!! 몇몇 사진이 회전돼서 표시된다.
private val getPicture =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val uri = result.data?.data ?: return@registerForActivityResult
val contentResolver = requireContext().contentResolver
kotlin.runCatching {
listOf(contentResolver.openInputStream(uri), contentResolver.openInputStream(uri))
}.onSuccess {
val bitmap = BitmapFactory.decodeStream(it.first())
viewModel.addPicture(bitmap.fixRotation(it.last()))
it.forEach { stream -> stream?.close() }
}.onFailure {
Timber.e(it)
}
}
object BitmapUtil {
fun Bitmap.fixRotation(inputStream: InputStream?): Bitmap {
if (inputStream == null) return this
val orientation =
ExifInterface(inputStream).getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED
)
return when (orientation) {
ExifInterface.ORIENTATION_ROTATE_90 -> rotateImage(90f)
ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage(180f)
ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage(270f)
ExifInterface.ORIENTATION_NORMAL -> this
else -> this
}
}
private fun Bitmap.rotateImage(angle: Float): Bitmap {
val matrix = Matrix()
matrix.postRotate(angle)
return Bitmap.createBitmap(this, 0, 0, width, height, matrix, true)
}
}
자 코드는 위와 같다.
하나씩 설명하면
일단 uri 를 갤러리에서 가져왔다. 그리고 우리는 InputStream 이 두개가 필요한다. 그렇기에
runcathing 을 사용했다(예외처리).
하나는 - Bitmap 을 추출할 때 필요한 애
또 하나는 - 이미지가 갖고 있는 정보를 가져오기 위함이다.
그래서 우리는 Bitmap 을 구한다. 하지만 회전된다. 왜냐!?
Most phone cameras are landscape, meaning if you take the photo in portrait, the resulting photos will be rotated 90 degrees. In this case, the camera software should populate the Exif data with the orientation that the photo should be viewed in.
대부분의 핸드폰 카메라는 가로이기에 세로로 찍으면 90도 회전된다는 것이다. 그래서 해당 처리가 필요하다. 이러한 작업은 보통 내가 받은 파일(카카오톡)은 해당 되지않고 본인이 직접 찍은 파일만 해당되는 듯 하다.
Bitmap.fixRotation