알파채널 개념을 개발한 토마스 포터와 톰 더프의 이름을 따서 만들었다.
대상(렌더링 대상의 콘텐츠)을 사용하여
소스(렌더 할 그래픽 개체)의 합성 결과 색상을 계산하는 방법으로
12개의 합성 연산자로 구성되어 있다.
구현해보기
private fun drawPorterDuffSample(canvas: Canvas) {
val sampleBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val sampleCanvas = Canvas(sampleBitmap)
sampleCanvas.drawBitmap(getCircleBitmap(), 0f, 0f, Paint())
sampleCanvas.drawBitmap(getRectangleBitmap(), 0f, 0f, Paint().apply {
xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC)
})
canvas.drawBitmap(sampleBitmap, 0f, 0f, Paint())
}
|
cs |
canvas의 drawRect, drawCircle과 같은 메소드에 적용하면 기대와 다른 결과가 나온다.
SRC, DST 모두 Bitmap으로 사용해야 기대한 결과를 볼 수 있었다.
위 코드에서 rectangleBitmap이 SRC, circleBitmap이 DST가 된다.
전체 코드
class Renderer {
private var width: Int = 0
private var height: Int = 0
private var centerX: Int = 0
private var centerY: Int = 0
fun setWidthAndHeight(width: Int, height: Int) {
this.width = width
this.height = height
centerX = width/2
centerY = height/2
}
fun onDraw(canvas: Canvas) {
drawPorterDuffSample(canvas)
}
private fun drawPorterDuffSample(canvas: Canvas) {
val sampleBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val sampleCanvas = Canvas(sampleBitmap)
sampleCanvas.drawBitmap(getCircleBitmap(), 0f, 0f, Paint())
sampleCanvas.drawBitmap(getRectangleBitmap(), 0f, 0f, Paint().apply {
xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC)
})
canvas.drawBitmap(sampleBitmap, 0f, 0f, Paint())
}
private fun getCircleBitmap() = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).apply {
val canvas = Canvas(this)
val paint = Paint().apply {
flags = Paint.ANTI_ALIAS_FLAG
color = Color.parseColor("#E9B639")
}
val radius = width*3.5f/10
canvas.drawCircle(radius, radius, radius, paint)
}
private fun getRectangleBitmap() = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).apply {
val canvas = Canvas(this)
val paint = Paint().apply {
flags = Paint.ANTI_ALIAS_FLAG
color = Color.parseColor("#4899C5")
}
val startTop = width*3/10
val endBottom = width*9/10
canvas.drawRect(
Rect(startTop, startTop, endBottom, endBottom),
paint
)
}
}
|
cs |
결과
위에 코드를 안드로이드 커스텀뷰에서 그린 결과이다.
안드로이드 커스텀뷰 코드
class CustomView(context: Context, attrs: AttributeSet?, defStyle: Int) : View(context, attrs, defStyle) {
constructor(context: Context) : this(context, null, 0)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
private val renderer = Renderer()
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
renderer.setWidthAndHeight(measuredWidth, measuredHeight)
}
override fun onDraw(canvas: Canvas) {
renderer.onDraw(canvas)
}
class Renderer {
private var width: Int = 0
private var height: Int = 0
private var centerX: Int = 0
private var centerY: Int = 0
fun setWidthAndHeight(width: Int, height: Int) {
this.width = width
this.height = height
centerX = width/2
centerY = height/2
}
fun onDraw(canvas: Canvas) {
drawPorterDuffSample(canvas)
}
private fun drawPorterDuffSample(canvas: Canvas) {
val sampleBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val sampleCanvas = Canvas(sampleBitmap)
sampleCanvas.drawBitmap(getCircleBitmap(), 0f, 0f, Paint())
sampleCanvas.drawBitmap(getRectangleBitmap(), 0f, 0f, Paint().apply {
xfermode = PorterDuffXfermode(PorterDuff.Mode.SCREEN)
})
canvas.drawBitmap(sampleBitmap, 0f, 0f, Paint())
}
private fun getCircleBitmap() = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).apply {
val canvas = Canvas(this)
val paint = Paint().apply {
flags = Paint.ANTI_ALIAS_FLAG
color = Color.parseColor("#E9B639")
}
val radius = width*3.5f/10
canvas.drawCircle(radius, radius, radius, paint)
}
private fun getRectangleBitmap() = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).apply {
val canvas = Canvas(this)
val paint = Paint().apply {
flags = Paint.ANTI_ALIAS_FLAG
color = Color.parseColor("#4899C5")
}
val startTop = width*3/10
val endBottom = width*9/10
canvas.drawRect(
Rect(startTop, startTop, endBottom, endBottom),
paint
)
}
}
}
|
cs |
참고
https://ko.wikipedia.org/wiki/%EC%95%8C%ED%8C%8C_%EC%B1%84%EB%84%90
https://developer.android.com/reference/android/graphics/PorterDuff.Mode
'Common' 카테고리의 다른 글
암호화와 해시 (0) | 2020.06.19 |
---|---|
Git 기본 명령어 (0) | 2019.08.19 |
Android Studio/IntelliJ 단축키 (Window) (0) | 2019.08.17 |
시간 표시 (0) | 2019.06.16 |