i want to achieve a circular image affect using PorterDuffXfermode as per this article and image: porterDuff tutorial
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:
What am i doing wrong. i tried all the porterDuff modes, nothing works.
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);
}