群组头像合成控件

package com.netease.nim.demo.common.imageView;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.ImageView;

import com.netease.nim.demo.R;
import com.netease.nim.uikit.common.util.media.BitmapDecoder;

import java.util.ArrayList;
import java.util.List;

/**
 * 群组头像合成控件
 */
public class GroupHeadImageView extends ImageView {

    public GroupHeadImageView(Context context) {
        super(context);
    }

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

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

    private static final int[] headIconResources = new int[]{
            R.drawable.head_icon_1, R.drawable.head_icon_2, R.drawable.head_icon_3
    };

    private static final Paint antiPaint = createAntiPaint();

    private static final Paint createAntiPaint() {
        Paint paint = new Paint();
        paint.setAntiAlias(true);

        return paint;
    }

    private static final Paint circlePaint = createCirclePaint();

    private static final Paint createCirclePaint() {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.WHITE);

        return paint;
    }

    private static final Paint destInPaint = createDestInPaint();

    private static final Paint createDestInPaint() {
        Paint paint = new Paint();

        paint.setAntiAlias(true);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

        return paint;
    }

    private static final Paint maskPaint = createMaskPaint();

    private static final Paint createMaskPaint() {
        Paint paint = new Paint();
        paint.setAntiAlias(true);

        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.BLACK);

        return paint;
    }

    private static final float o = 11f / 36f;
    private static final float i = 10f / 36f;

    private List<Bitmap> bitmaps;

    /**
     * 确定三个RECT(外圆,内圆),左上角的起点
     */
    private static final float[][][] p = new float[][][]{
            new float[][]{
                    new float[]{0.5f - o, 0},
                    new float[]{0.5f - i, o - i},
            },
            new float[][]{
                    new float[]{1.0f - o * 2, 1.0f - o * 2},
                    new float[]{1.0f - o * 2 + o - i, 1.0f - o * 2 + o - i},
            },
            new float[][]{
                    new float[]{0, 1.0f - o * 2},
                    new float[]{o - i, 1.0f - o * 2 + o - i},
            },

    };

    public void loadResourceImage() {
        int width = getWidth();
        int height = getHeight();

        this.bitmaps = new ArrayList<>(3);
        for (int i = 0; i < 3; i++) {
            bitmaps.add(BitmapDecoder.decodeSampled(getResources(), headIconResources[i], width, height));
        }

        invalidate();
    }

    @Override
    public void draw(Canvas canvas) {
        // bounds
        int width = getWidth();
        int height = getHeight();

        super.draw(canvas);

        // to canvas
        join3(canvas, width, height, this.bitmaps);
    }

    private final void join3(Canvas canvas, int destWidth, int destHeight, List<Bitmap> bitmaps) {
        if (bitmaps == null) {
            return;
        }

        int size = Math.min(p.length, bitmaps.size());
        for (int index = size - 1; index >= 0; index--) {
            Bitmap bitmap = bitmaps.get(index);

            // 矩形区域
            float[] posOut = new float[]{
                    p[index][0][0] * destWidth, p[index][0][1] * destHeight
            };

            // 外圈内圈半径
            float rdsOut = destWidth * o;
            float rdsIn = destWidth * i;

            // 头像层
            RectF rect = new RectF(posOut[0], posOut[1], posOut[0] + 2 * rdsOut, posOut[1] + 2 * rdsOut);
            canvas.saveLayer(rect, null, Canvas.ALL_SAVE_FLAG);
            // 对头像位图进行缩放
            Matrix matrix = new Matrix();
            matrix.postScale((float) destWidth / bitmap.getWidth(), (float) destHeight / bitmap.getHeight());
            matrix.postScale(2 * o, 2 * o);

            canvas.translate(posOut[0], posOut[1]);
            canvas.drawBitmap(bitmap, matrix, antiPaint);
            canvas.translate(-posOut[0], -posOut[1]);

            Paint paint = circlePaint;
            paint.setStrokeWidth(rdsOut - rdsIn);
            canvas.drawCircle(posOut[0] + rdsOut, posOut[1] + rdsOut, rdsOut, paint);

            // MASK层
            canvas.saveLayer(rect, destInPaint, Canvas.ALL_SAVE_FLAG);
            canvas.drawCircle(posOut[0] + rdsOut, posOut[1] + rdsOut, rdsOut, maskPaint);

            // MASK层与头像层合并->MERGE层
            canvas.restore();

            // MERGE层与DEFAULT层合并
            canvas.restore();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值