Canvas를 사용하여 Bitmap에서 정원 Bitmap을 만드는 과정을 작성한 이야기

하고 싶은 일



한 이미지에서 썸네일 아이콘을 만들어 표시하는 처리가 필요하게 되었으므로 Canvas를 사용하여 구현해 보았습니다.


예를 들어 이런 넥타이의 이미지가 있었다고 하면, 원하는 것은 다음과 같은 아이콘이 됩니다.

확대 축소는 하지 않고, 중심 부분을 잘 둥글게 잘라내는 처리를 하는 경우, 이하와 같은 실장이 됩니다.

실제 소스 코드


    private fun getCroppedBitmap(bitmap: Bitmap): Bitmap {
        val size = Math.min(bitmap.width, bitmap.height)
        val output = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(output)

        val paint = Paint()

        paint.isAntiAlias = true
        canvas.drawARGB(0, 0, 0, 0)
        canvas.drawCircle(size / 2f, size / 2f, size / 2f, paint)
        paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
        val max = Math.max(bitmap.width, bitmap.height)
        val start = (size - max) / 2
        val left = if (bitmap.width < bitmap.height) 0 else start
        val top = if (bitmap.height < bitmap.width) 0 else start
        val rect = Rect(left, top, bitmap.width + left, bitmap.height + top)
        canvas.drawBitmap(bitmap, Rect(0, 0, bitmap.width, bitmap.height), rect, paint)
        return output
    }

해설



하는 일은 그리 어렵지 않습니다.
우선, 출력처의 Bitmap을 size 지정으로 작성합니다. 이 때 size는 원래 이미지의 폭/높이 중 작은 쪽을 지정합니다.
그런 다음 Canvas와 Paint를 준비합니다.
이번에는 원형으로 이미지를 자르기 때문에 Paint는 쟈기가 눈에 띄지 않게 isAntiAlias를 true로 설정합니다 (자세한 내용은 안티 앨리어스 참조).
캔버스는 투명하고 채우고, drawCircle(中心点のx座標,中心点のy座標,半径,paint) 에서 size의 반경으로 방금 중앙에 원을 그립니다.paint.xfermode 를 설정하기 전의 drawCircle 가 DST, 그 후의 drawBitmap 가 SRC 이므로, 이미지가 원 안에 들어가게 하려면 PorterDuffXfermode(PorterDuff.Mode.SRC_IN)paint.xfermode 로 설정합니다.
마지막으로 잘라내는 rect를 결정해 drawBitmap 하는 것으로, 묘화 처리는 완료입니다.

좋은 웹페이지 즐겨찾기