본문 바로가기
안드로이드

[android] PorterDuffXfermode 활용하여 테두리 만들기

by 아이디생성자 2022. 12. 20.

카메라위에 포커스 영역을 이쁘게 만들기 위해 오랜만에 사용하면서 기록을 남긴다.

 

이녀석 활용은 아직도 사용방법이 낯설다.

 

tint에 보여서 손쉽게 사용해보려했지만 막상 적용이 안된다.

 

귀찮지만 canvas를 꺼내 들어야한다.

 

 

1. activity에 이미지뷰를 하나 추가한다.

<ImageView
    android:id="@+id/iv_board"
    android:layout_width="300dp"
    android:layout_height="300dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

 

 

2. 테두리가 될 drawable을 내맘대로 하나 만든다.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:shape="rectangle">
            <solid
                android:color="#00000000"/>
        </shape>
    </item>

    <item>
        <shape
            android:shape="rectangle">

            <size
                android:width="300dp"
                android:height="300dp"/>

            <corners
                android:radius="24dp"/>

            <gradient
                android:startColor="#ff0000"
                android:centerColor="#00ff00"
                android:endColor="#0000ff"/>
        </shape>
    </item>
</layer-list>

 

 

3. 적용 코드

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val ivBoard = findViewById<ImageView>(R.id.iv_board)
    val mWidth = dpToPx(300f)
    val mHeight = dpToPx(300f)
    val radius = dpToPx(24f).toFloat()
    val strokeWidth = dpToPx(6f)
    val bitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bitmap)

    val srcOutPaint = Paint().apply {
        isAntiAlias = true
        xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)
    }

    canvas.drawBitmap(bitmap, 0f, 0f, Paint())

    val bg = (getDrawable(R.drawable.bg_custom) as LayerDrawable)
    bg.setBounds(0,0,mWidth, mHeight)
    bg.draw(canvas)

    canvas.drawRoundRect(
        strokeWidth.toFloat(),
        strokeWidth.toFloat(),
        mWidth.toFloat() - strokeWidth,
        mHeight.toFloat() - strokeWidth,
        radius,
        radius,
        srcOutPaint
    )

    ivBoard.setImageBitmap(bitmap)
}

fun dpToPx(dp: Float): Int {
    return Math.round(dp * Resources.getSystem().displayMetrics.density)
}

 

 

이렇게 코드를 작성하게 되면, canvas에 그려진 bg_custom 위에 src_out 페인트가 적용된 roundRect을 그리면서 겹치는 부분이 사라지고 테두리가 생기게 된다.

 

 

※ 좀 더 다양한 porterDuff 활용법은 아래 링크를 참조

 

https://developer.android.com/reference/android/graphics/PorterDuff.Mode

 

PorterDuff.Mode  |  Android Developers

 

developer.android.com

 

 

결과화면

 

댓글