如何在ImageView中屏蔽/裁剪矩形

时间:2020-12-20 08:57:57

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:

我创建了一个自定义ImageView来在图像中创建一个透明矩形,以使其后面的ImageView可见。但是,我无法做到对。我已经看了很多其他的答案,这就是我想出的:

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布局:

<?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.

我在左边看到了照片,但我希望它看起来像右边的照片。请注意,正常的ImageView drawable是MaskImageView照片的灰度版本。

如何在ImageView中屏蔽/裁剪矩形

2 个解决方案

#1


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.

我写了一个简单的View,它扩展了ImageView,它可以完成你想做的事情。要使用它,您需要做的就是给它一个Rect,它将您想要的区域定义为灰度。

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.

我已经测试了它,似乎效果很好。这应该让你开始。

#2


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.

我认为你不能真正做到这一点。我建议改为访问底部ImageView的位图,并将该位图的区域绘制到顶部的ImageView上。您可以获得相同的效果,但不需要使ImageView透明。

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

根据您将原始图像放入ImageView的方式,您可以使用它来获取您想要绘制的位图:

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

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

然后你必须从该位图复制一个方块,你可以使用这个代码:

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

#1


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.

我写了一个简单的View,它扩展了ImageView,它可以完成你想做的事情。要使用它,您需要做的就是给它一个Rect,它将您想要的区域定义为灰度。

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.

我已经测试了它,似乎效果很好。这应该让你开始。

#2


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.

我认为你不能真正做到这一点。我建议改为访问底部ImageView的位图,并将该位图的区域绘制到顶部的ImageView上。您可以获得相同的效果,但不需要使ImageView透明。

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

根据您将原始图像放入ImageView的方式,您可以使用它来获取您想要绘制的位图:

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

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

然后你必须从该位图复制一个方块,你可以使用这个代码:

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