androidporter-duff

Android Paint - PorterDuffXfermode SRC_IN not working


i want to achieve a circular image affect using PorterDuffXfermode as per this article and image: porterDuff tutorial

enter image description here

So i have destination circle which is this

and i have a source image which is this:

and i created a custom imageview and in the ondraw i was going to draw a circular image like the tutorial. so my code for doing that looks like this:

    class ImageCutomView : ImageView {
        constructor(p0: Context) : super(p0)
        constructor(p0: Context, p1: AttributeSet?) : super(p0, p1)
        constructor(p0: Context, p1: AttributeSet?, p2: Int) : super(p0, p1, p2)


        override fun onDraw(canvas: Canvas?) {
            super.onDraw(canvas)
    val sideLengthY = measuredHeight
    val sideLengthX = measuredWidth
    val fullRect = Rect(0,0, sideLengthX,sideLengthY)
    if (canvas != null) {
            if (canvas != null) {
                val paint = Paint()

                val destination = BitmapFactory.decodeResource(
                    context.resources,
                    R.drawable.black_circle
                )

                val source = BitmapFactory.decodeResource(
                    context.resources,
                    R.drawable.bikeriding
                )
                canvas.drawBitmap(destination, null, fullRect, paint)

 paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)

                canvas.drawBitmap(source, null, fullRect, paint)
            }
        }
    }

Now the problem is that it does not draw a circular image. here is how i been using the custom view:

    <?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:id="@+id/motion_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent"
>

    <com.example.mycustomVews.ImageCutomView
            android:id="@+id/red_star"
            android:layout_width="400dp"
            android:layout_height="400dp" 
            android:background="@color/aqua_green"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

but when it renders it looks like this:

enter image description here

What am i doing wrong. i tried all the porterDuff modes, nothing works.


Solution

  • Here is the answer to this question PorterDuffXfermode DST_IN not working as expected

    He says that:

    "Be careful though: it will work only in a transparent Bitmap or in layer. When you draw directly on screen, the destination is already filled by the window background."

    You could also clip the canvas before and then fill the clipped canvas, so you would do in Java:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    
        Path path = new Path();
    
        // IN CASE OF RECTANGLE
        path.addCircle(getWidth()/2f, getHeight()/2f, Math.min(getWidth(), getHeight())/2f, Path.Direction.CW);
    
        canvas.clipPath(path);
    
    
        // CENTERED POSITION, NOT SCALED BITMAP
        float l = (getWidth()-yourSourceBitmap.getWidth())/2f;
        float t = (getHeight()-yourSourceBitmap.getHeight())/2f;
    
        // DRAW INTO CLIPPED
        canvas.drawBitmap(yourSourceBitmap, l, t, null);
    
    
    }