Android Canvas Clip 裁剪

上一章节我们学习了裁剪 API 中的 clipRect() ,本章节我们来讲讲另一个 API clipPath()

clipPath()

clipPath() 按照路径裁剪,可以是开放或闭合的曲线,线构成的复杂的集合图形

clipPath() 只有只有一个方法,使用方式非常简单,自己绘制一个 Path 作为参数即可

boolean clipPath(Path path)

另一个在 API 26+ 中被废弃

clipPath(Path path, Region.Op op)

范例

我们使用 clipPath() 来制作一个圆角头像

  1. 创建一个 空的 Android 项目 cn.twle.android.ClipPath

  2. 下载 /static/i/android/avatar.png,并把所有的图片拖到 res/drawable 目录下

  3. 自定义一个 View 类 RoundImageView.java

    package cn.twle.android.clippath;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.PaintFlagsDrawFilter;
    import android.graphics.Path;
    import android.graphics.Rect;
    import android.support.v7.widget.AppCompatImageView;
    import android.util.AttributeSet;
    
    public class RoundImageView extends AppCompatImageView {
    
        private Bitmap mBitmap;
        private Rect mRect = new Rect();
        private PaintFlagsDrawFilter pdf = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG);
        private Paint mPaint = new Paint();
        private Path mPath=new Path();
        public RoundImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        //传入一个Bitmap对象
        public void setBitmap(Bitmap bitmap) {
            this.mBitmap = bitmap;
        }
    
        private void init() {
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
            mPaint.setAntiAlias(true);// 抗锯尺
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if(mBitmap == null)
            {
                return;
            }
            mRect.set(0,0,getWidth(),getHeight());
            canvas.save();
            canvas.setDrawFilter(pdf);
            mPath.addCircle(getWidth() / 2, getWidth() / 2, getHeight() / 2, Path.Direction.CCW);
            canvas.clipPath(mPath);
            canvas.drawBitmap(mBitmap, null, mRect, mPaint);
            canvas.restore();
        }
    }
    
  4. 修改 activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:gravity="center"   
        android:layout_width="match_parent"    
        android:layout_height="match_parent"    
        android:orientation="horizontal">
    
        <cn.twle.android.clippath.RoundImageView
                android:id="@+id/img_round"
                android:layout_width="128dp"
                android:layout_height="128dp"
                android:layout_margin="5px"/>
    </LinearLayout>
    
  5. 修改 MainActivity.java 设置 setContentView(new MsView(MainActivity.this))

    package cn.twle.android.clippath;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    
    public class MainActivity extends AppCompatActivity {
    
        private RoundImageView img_round;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            img_round = (RoundImageView) findViewById(R.id.img_round);
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.avatar);
            img_round.setBitmap(bitmap);
        }
    }
    

这种方式制作的圆角 ImageView 会有锯齿明显,即使为 PaintCanvas 设置了 抗锯齿也没用

参考文档

官方 API 文档Canvas

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.