如何在 ImageView 中 mask/crop 一个矩形
How to mask/crop a rectangle in ImageView
我创建了一个自定义 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;
}
}
这是 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>
我得到了左边的照片,但我希望它看起来像右边的照片。请注意,正常的 ImageView
可绘制对象是 MaskImageView
.
照片的灰度版本
我认为您实际上无法做到这一点。我建议改为访问底部 ImageView 的位图并将该位图中的区域绘制到顶部 ImageView 上。您会得到相同的效果,但不需要使 ImageView 透明。
根据您将原始图像放入 ImageView 的方式,您可以使用它来获取要绘制的位图:
然后您必须从该位图中复制一个正方形,您可以使用以下代码执行此操作:
我写了一个简单的 View
,它扩展了 ImageView
,它可以完成您想要做的事情。要使用它,您需要做的就是给它一个 Rect,它将您想要的区域定义为灰度。
代码如下:
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);
}
}
我已经测试过了,它似乎运行良好。这应该可以帮助您入门。
我创建了一个自定义 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;
}
}
这是 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>
我得到了左边的照片,但我希望它看起来像右边的照片。请注意,正常的 ImageView
可绘制对象是 MaskImageView
.
我认为您实际上无法做到这一点。我建议改为访问底部 ImageView 的位图并将该位图中的区域绘制到顶部 ImageView 上。您会得到相同的效果,但不需要使 ImageView 透明。
根据您将原始图像放入 ImageView 的方式,您可以使用它来获取要绘制的位图:
然后您必须从该位图中复制一个正方形,您可以使用以下代码执行此操作:
我写了一个简单的 View
,它扩展了 ImageView
,它可以完成您想要做的事情。要使用它,您需要做的就是给它一个 Rect,它将您想要的区域定义为灰度。
代码如下:
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);
}
}
我已经测试过了,它似乎运行良好。这应该可以帮助您入门。