본문 바로가기
안드로이드 프로그래밍

안드로이드 Glide 이미지 회전 시키기(자동 회전 방지)

by Loyal 2021. 4. 9.
반응형

찍은 사진을 Glide를 통해 보여주려고 했는데, 핸드폰에서 90도가 뒤집혀서 나오는 경우가 발생했다. 세로 화면으로 사진을 찍었음에도 불구하고, Glide를 통해 ImageView에 이미지를 띄웠을 때 가로로 사진이 나오는 것이다.

 

이를 해결하기 위해 해결 방법을 찾아봤었는데, 아래 링크를 참고를 했지만 제대로 동작하지 않았다.

https://futurestud.io/tutorials/glide-how-to-rotate-images

 

Glide — How to Rotate Images

In order to be competitive in today's Google Play environment, your app needs to be polished. Images need to be used consistently and loaded smoothly. Learn how to create and completely customize image-rich Android apps with our book on Glide. Save yoursel

futurestud.io

그래서 다른 원인을 찾아보았는데, 사진의 데이터 문제였다. 핸드폰으로 사진을 찍으면 그에 대한 메타 데이터로 exif가 저장이 되는데, 이 exif 안에는 사진을 찍은 기기, 찍었을 때의 회전 각도, 찍은 위치 등등 여러가지가 저장이 된다. 여기서 직접적으로 사용할 것은 찍었을 때의 회전 각도이다.

 

사실 Glide는 exif의 회전각도까지 생각해서 이미지를 출력해주는 것 같은데, 나는 찍은 이미지를 resize하고, 그 비트맵을 Glide로 불러오는 코드라서, exif는 비트맵에 따로 저장이 되지 않았던 것 같다.

 

일단 RotateTransform 클래스를 생성해주고 아래와 같은 코드를 입력해주자.

import android.graphics.Bitmap
import android.graphics.Matrix
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
import java.security.MessageDigest

class RotateTransform(rotateRotationAngle: Float) : BitmapTransformation() {
    private var rotateRotationAngle = 0f
    init {
        this.rotateRotationAngle = rotateRotationAngle
    }

    override fun updateDiskCacheKey(messageDigest: MessageDigest) {
        messageDigest.update(("rotate$rotateRotationAngle").toByte());
    }

    override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap {
        val matrix = Matrix()
        matrix.postRotate(rotateRotationAngle)
        return Bitmap.createBitmap(toTransform, 0, 0, toTransform.width, toTransform.height, matrix, true)
    }
}

그리고 Glide를 사용할 액티비티에서 이 함수를 사용하면 되는데, 이전에 작성했던 포스트와 마찬가지로 option에서 설정을 해줄 것이다.

studyforcoding.tistory.com/8

 

Glide 이미지 갱신되지 않는 오류 해결

Glide 라이브러리를 사용하던 중, ImageView의 이미지가 갱신이 되지 않는 현상이 생겼다. 먼저 어플의 흐름에 대해서 설명하자면, 사진을 찍으면 해당 이미지를 다른 액티비티에서 Glide를 사용하여

studyforcoding.tistory.com

val options = RequestOptions().skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE)
try {
    when(ExifInterface(File(cacheDir,"temp.jpg")).rotationDegrees) {
        90 -> options.transform(RotateTransform(90f))
        180 -> options.transform(RotateTransform(180f))
        270 -> options.transform(RotateTransform(270f))
    }
} catch (e: IOException) {
    e.printStackTrace()
}
Glide.with(this).load(File(cacheDir,"resize.jpg")).apply(options).into(img_imageview)

위 코드에 대해서 설명하면, 사진 파일이 있는 경로에 ExifInterface를 생성하여 rotationDegrees를 불러온다. 그렇게 하면 return 값으로 0, 90, 180, 270이 나오는데, 이 값이 사진을 찍었을 때 회전된 각도이다. options에서 when문으로 각도에 맞게 회전을 시켜준후 Glide로 이미지를 load하면 되는데, 위 코드에서 ExifInterface에서 불러오는 파일과 Glide에서 불러오는 파일이 다른 이유는 게시글 가장 위에서 설명했듯이 temp.jpg 같은 경우 카메라로 직접 찍은 사진이라 Exif가 저장되어 있는 파일이고, Glide로 불러올 이미지는 resize된 이미지인 resize.jpg이기 때문이다.

 

위 코드 2개면 회전에 대한 대처가 가능할 것이다.

반응형