본문 바로가기
안드로이드 코틀린

[Android][코틀린] 비트맵 합치기 PorterDuff.Mode

by teamnova 2023. 12. 15.

오늘은 코틀린으로 안드로이드 PorterDuff.Mode 를 사용하여 비트맵 두개를 합치는 코드를 구현해보겠습니다.

자바 버전은 해당 링크로 가주세요 >> https://stickode.tistory.com/948

 

[Android][Java] 비트맵 합치기 PorterDuff.Mode

오늘은 안드로이드 PorterDuff.Mode 를 사용하여 비트맵 두개를 합치는 코드를 구현해보겠습니다. PorterDuff.Mode은 안드로이드에서 그래픽 처리를 위한 모드를 지정하는 열거형(enum)입니다. 이 모드는

stickode.tistory.com

 

PorterDuff.Mode은 안드로이드에서 그래픽 처리를 위한 모드를 지정하는 열거형(enum)입니다. 이 모드는 두 그림을 합성(composite)할 때 사용됩니다. 일반적으로 두 그림이 겹쳐질 때 어떻게 합성할지를 결정하는데 사용됩니다.

  1. SRC_OVER:
    • 첫 번째 그림 위에 두 번째 그림을 덮습니다.
  2. SRC_IN:
    • 첫 번째 그림과 두 번째 그림의 겹치는 부분만 보여줍니다.
  3. SRC_OUT:
    • 첫 번째 그림에서 두 번째 그림의 겹치지 않는 부분만 보여줍니다.
  4. SRC_ATOP:
    • 두 번째 그림을 첫 번째 그림 위에 놓고, 두 그림이 겹치는 부분만 보여줍니다.
  5. DST_OVER:
    • 두 번째 그림 위에 첫 번째 그림을 덮습니다.
  6. DST_IN:
    • 두 번째 그림과 첫 번째 그림의 겹치는 부분만 보여줍니다.
  7. DST_OUT:
    • 두 번째 그림에서 첫 번째 그림의 겹치지 않는 부분만 보여줍니다.
  8. DST_ATOP:
    • 첫 번째 그림을 두 번째 그림 위에 놓고, 두 그림이 겹치는 부분만 보여줍니다.
  9. CLEAR:
    • 겹치는 부분을 완전히 투명하게 만듭니다.
  10. XOR:
    • 겹치는 부분을 제외한 나머지 부분만 보여줍니다.
  11. DARKEN:
    • 두 그림 중 어두운 부분을 표시합니다.
  12. LIGHTEN:
    • 두 그림 중 밝은 부분을 표시합니다.

등등 다양한 모드가 있으며, 이들을 조합하면 다양한 그래픽 효과를 얻을  있습니다. PorterDuff.Mode 주로 그림이나 이미지를 합성하는 작업에서 사용되며, 그래픽 처리와 관련된 다양한 시나리오에서 유용하게 활용됩니다.

 

안드로이드 공식 문서에서 해당 내용을 확인하시고 다양한 예를 한번 보시면 좋습니다.

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

 

PorterDuff.Mode  |  Android Developers

 

developer.android.com

MainActivity.kt

class MainActivity : AppCompatActivity() {
    // 필요한 뷰 및 비트맵 변수 선언
    private lateinit var imageView: ImageView
    private lateinit var imageView2: ImageView
    private lateinit var imageView3: ImageView
    private lateinit var bitmap1: Bitmap
    private lateinit var bitmap2: Bitmap
    private lateinit var button: Button

    // 액티비티 생성 시 호출되는 메서드
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 레이아웃 설정
        setContentView(R.layout.activity_main)
        // 뷰와 버튼 초기화
        imageView = findViewById(R.id.imageView)
        imageView2 = findViewById(R.id.imageView2)
        imageView3 = findViewById(R.id.imageView3)
        button = findViewById(R.id.button)

        // 첫 번째 이미지뷰에 비트맵 설정
        bitmap1 = BitmapFactory.decodeResource(applicationContext.resources, R.drawable.img_1)
        imageView.setImageBitmap(bitmap1)

        // 두 번째 이미지뷰에 비트맵 설정
        bitmap2 = BitmapFactory.decodeResource(applicationContext.resources, R.drawable.img)
        imageView2.setImageBitmap(bitmap2)

        // 버튼에 클릭 리스너 등록
        button.setOnClickListener {
            imageCombine()
        }
    }

    private fun imageCombine() {
        // 첫 번째 이미지뷰에서 비트맵 가져오기
        val drawable1 = imageView.drawable as BitmapDrawable
        val dst = drawable1.bitmap

        // 두 번째 이미지뷰에서 비트맵 가져오기
        val drawable2 = imageView2.drawable as BitmapDrawable
        val src = drawable2.bitmap

        // 새로운 비트맵 생성
        val bitmap = Bitmap.createBitmap(dst.width, dst.width, Bitmap.Config.ARGB_8888)

        // 비트맵을 그릴 캔버스 생성
        val canvas = Canvas(bitmap)

        // 페인트 객체 생성
        val paint = Paint()
        // 첫 번째 이미지 그리기
        canvas.drawBitmap(dst, 0f, 0f, paint)
        // 포터더프 모드를 이용하여 두 번째 이미지를 그리기
        paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)
        canvas.drawBitmap(src, 600f, 0f, paint)

        // 세 번째 이미지뷰에 새로운 비트맵 설정
        imageView3.setImageBitmap(bitmap)
    }
}

 

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <ImageView
        android:id="@+id/imageView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <ImageView
        android:id="@+id/imageView3"
        android:layout_width="300dp"
        android:layout_height="300dp"
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView"
        tools:srcCompat="@tools:sample/avatars" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="200dp"
        android:layout_height="200dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>