4

I have created a custom ImageView to create a transparent rectangle within the image so to make the ImageView behind it visible. However, I can't get it right. I've looked at many other answers and this is what I have came up with:

public class MaskImageView extends ImageView {
    private Paint maskPaint;

    public MaskImageView(Context context) {
        super(context);
        init();
    }

    public MaskImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MaskImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public MaskImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    public void init() {
        maskPaint = new Paint();
        maskPaint.setColor(Color.TRANSPARENT);
        maskPaint.setAntiAlias(true);
        maskPaint.setStyle(Paint.Style.FILL);
        maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(100, 400, 900, 900, maskPaint);
    }

    public void setMaskWidth(int width) {
        maskWidth = width;
    }
}

And this is the XML layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_red_dark"
        android:scaleType="centerCrop"
        android:src="@drawable/blackwhite" />


    <io.example.test.MaskImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_red_dark"
        android:scaleType="centerCrop"
        android:src="@drawable/color" />
</RelativeLayout>

I get the photo on the left but I want it to look like the photo on the right. Note that the normal ImageView drawable is the grayscale version of the photo of MaskImageView.

enter image description here

Nasir
  • 1,982
  • 4
  • 19
  • 35

2 Answers2

2

I wrote a simple View which extends ImageView which does what you're trying to do. To work with it, all you need to do is give it a Rect which defines the zone you want as grayscale.

Here's the code:

public class MaskImageView extends ImageView
{
    private Rect mMaskRect;

    public MaskImageView(Context context)
    {
        super(context);
        init();
    }

    public MaskImageView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        init();
    }

    public MaskImageView(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init()
    {
        mMaskRect = new Rect();    
    }

    // Use this to define the area which should be masked. 
    public void setRect(Rect rect)
    {
        mMaskRect.set(rect);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        canvas.clipRect(mMaskRect, Region.Op.DIFFERENCE);
        super.onDraw(canvas);
    }
}

I've tested it and it seems to work well. This should get you started.

Gil Moshayof
  • 16,633
  • 4
  • 47
  • 58
0

I don't think you can actually do this.. What I would recommend instead is getting access to the bottom ImageView's bitmap and drawing the region from that bitmap onto your top ImageView. You get the same effect, but you don't need to make the ImageView transparent.

Depending on how you got the original image into the ImageView you can use this to get the bitmap you want to draw:

https://stackoverflow.com/a/8306683/3760854

Then you'll have to copy a square from that bitmap, which you can do using this code:

https://stackoverflow.com/a/8180576/3760854

Community
  • 1
  • 1
martin_xs6
  • 73
  • 8
  • This sounds like an interesting idea to repaint that portion of the behind image on this one. I'm going to try it and will let you know. – Nasir May 13 '15 at 13:30