PorterDuffXfermode实现圆角、圆形头像

上篇博客中,我全面介绍了Xfermode相关的知识点,如果还没看过的小伙伴,建议你先去看上篇博客——初始Xfermode,对PorterDuffXfermode的18种模式做了详细的介绍,而且我也自己实现了官网的18种效果。这篇文章主要是记录下,PorterDuffXfermode在开发中常见的应用,比如:实现圆角、圆形等等,只要你可以画出来的形状都可以做。

效果图:

这里写图片描述

DST_IN模式:

以上效果图就是用的这种模式,我们先看下这种模式的效果:

这里写图片描述

上次我们已经说过了:显示目标图与源图的交集,且只显示目标图部分(可能你看到这里一脸懵逼,所以呀,去看上篇文章,你就懂了)

那么我们的圆角图到底怎么实现的呢?

思路:根据我们的DST_IN模式,可以先画出一个圆角矩形作为源图,然后画笔对象设置为DST_IN模式,接着把我们的设置为头像的图片画上去,就可以了。

下面看下代码:

public class PorterDuffXfermodeView extends ImageView {


    private static final Xfermode sXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
    private Bitmap mMaskBitmap;
    private Paint mPaint;
    int type;//绘制形状
    public static final int CIRCLE = 0;//原型
    public static final int ROUNDRECT = 1;//圆角
    public static final int HEART = 2;//心形
    public static final int OVAL = 3;//椭圆

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

    public PorterDuffXfermodeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
        TypedArray array = context.obtainStyledAttributes(attrs,
                R.styleable.pdxView);
        type = array.getInt(R.styleable.pdxView_type, 0);// 默认为Circle
        array.recycle();
    }

    public PorterDuffXfermodeView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        Bitmap bitmap = null;
        Drawable drawable = getDrawable();
        if (drawable != null) {
            bitmap = Bitmap.createBitmap(getWidth(),
                    getHeight(), Bitmap.Config.ARGB_8888);
            Canvas bitmapCanvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, getWidth(), getHeight());
            drawable.draw(bitmapCanvas);

            if (mMaskBitmap == null || mMaskBitmap.isRecycled()) {
                switch (type) {
                    case CIRCLE:
                        mMaskBitmap = getBitmapCircle(getWidth(), getHeight());
                        break;
                    case ROUNDRECT:
                        mMaskBitmap = getBitmapRoundRect(getWidth(), getHeight());
                        break;
                    case HEART:
                        mMaskBitmap = getBitmapHeart(getWidth(), getHeight());
                        break;
                    case OVAL:
                        mMaskBitmap = getBitmapOval(getWidth(), getHeight());
                        break;

                }

            }

            mPaint.setXfermode(sXfermode);
            bitmapCanvas.drawBitmap(mMaskBitmap, 0.0f, 0.0f, mPaint);
//这里混合模式,上面设置完后,要再次设置为null
            mPaint.setXfermode(null);
            canvas.drawBitmap(bitmap, 0.0f, 0.0f, mPaint);
        }
    }
//圆角矩形
    public static Bitmap getBitmapRoundRect(int width, int height) {
        Bitmap bitmap = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLACK);
        canvas.drawRoundRect(new RectF(0.0f, 0.0f, width, height), 50, 50, paint);

        return bitmap;
    }
//圆形
    public static Bitmap getBitmapCircle(int width, int height) {
        Bitmap bitmap = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.RED);
        canvas.drawCircle(width / 2, height / 2, Math.min(width / 2, height / 2), paint);
        return bitmap;
    }
//心形
    public static Bitmap getBitmapHeart(int width, int height) {
        Bitmap bitmap = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLACK);
        Path path = new Path();
        path.addArc(200, 200, 400, 400, -225, 225);
        path.arcTo(400, 200, 600, 400, -180, 225, false);
        path.lineTo(400, 542);
        canvas.drawPath(path, paint);
        return bitmap;
    }
//椭圆
    public static Bitmap getBitmapOval(int width, int height) {
        Bitmap bitmap = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLACK);
        canvas.drawOval(new RectF(0.0f, 0.0f, width, height), paint);
        return bitmap;
    }


}

源码在这里github喜欢的话,给个start哦~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Android Studio中实现圆形头像的方法有以下几种: 1. 使用ImageView的圆形裁剪功能 在布局文件中添加一个ImageView,并设置其src属性为头像图片,然后设置其scaleType为centerCrop,最后使用android:background属性设置圆形背景即可实现圆形头像。 ``` <ImageView android:id="@+id/avatar" android:layout_width="100dp" android:layout_height="100dp" android:scaleType="centerCrop" android:src="@drawable/avatar" android:background="@drawable/circle"/> ``` 其中,circle.xml是一个圆形背景的drawable文件,代码如下: ``` <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#FFFFFF" /> </shape> ``` 2. 使用Glide库实现圆形头像 Glide是一款强大的图片加载库,可以方便地加载网络或本地图片,并提供了很多图片处理的功能,包括圆形裁剪。 在布局文件中添加一个ImageView,并设置其src属性为空,然后在Java代码中使用Glide加载头像图片,并使用Glide提供的Transformations.circleCrop()方法进行圆形裁剪,最后设置到ImageView中即可。 ``` <ImageView android:id="@+id/avatar" android:layout_width="100dp" android:layout_height="100dp"/> Glide.with(this) .load("http://xxx.com/avatar.png") .apply(RequestOptions.circleCropTransform()) .into(imageView); ``` 3. 使用自定义View实现圆形头像 自定义View是一种更灵活、更可定制化的实现方式。可以继承View或其子类,然后在onDraw方法中绘制头像图片,并使用canvas.drawCircle()方法绘制圆形背景。 ``` public class CircleImageView extends ImageView { private Paint mPaint; public CircleImageView(Context context) { super(context); init(); } public CircleImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(Color.WHITE); } @Override protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (drawable == null) { super.onDraw(canvas); return; } Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); Bitmap circleBitmap = getCircleBitmap(bitmap); canvas.drawBitmap(circleBitmap, 0, 0, null); } private Bitmap getCircleBitmap(Bitmap bitmap) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); int width = bitmap.getWidth(); int height = bitmap.getHeight(); int radius = Math.min(width, height) / 2; canvas.drawCircle(width / 2, height / 2, radius, mPaint); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, 0, 0, mPaint); return output; } } ``` 在布局文件中使用自定义View即可。 ``` <com.example.CircleImageView android:id="@+id/avatar" android:layout_width="100dp" android:layout_height="100dp" android:src="@drawable/avatar"/> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值