自定义圆形图片

这里写图片描述

使用到的知识: Paint画笔 Canvas 画布
* 1.自定义圆环
* 2.绘制圆形图片,是通过 图层之间相互影响实现的。
* 3.图像的等比例裁切计算原则
* 4.图片压缩方法(暂时没有使用)

不造轮子,只分析原理

package version1;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.nuoyuan.t.R;

/**
 * Created by weichyang on 2016/6/1. 在view 包下为什么不可以使用
 * 1.自定义圆环的
 * 2.绘制圆形图片,是通过 图层之间相互影响实现的。
 * 3.图像的等比例裁切计算原则
 * 4.图片压缩方法
 */
public class CircleImageView extends ImageView {

    private Paint mPaint;
    private int mViewWidth;
    private int mViewHeight;
    private RectF rectF = new RectF(); //四个定点
    private int mRadius = 300;

    public CircleImageView(Context context) {
        super(context);
        initPaint();
    }

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

    /**
     * 初始化的画笔
     */
    private void initPaint() {
        mPaint = new Paint();
        mPaint.setStrokeWidth(2);
        mPaint.setAntiAlias(true);
        mPaint.setColor(getResources().getColor(android.support.design.R.color.material_blue_grey_800));

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawArc(rectF, 0, 360, true, mPaint);
        //画圆形头像
        Bitmap bm = drableToBitmap();
        // 裁剪一个图片的过程
        Bitmap bitmap = getCroppedRoundBitmap(bm, mViewWidth / 2);

        canvas.drawBitmap(bitmap, rectF.left, rectF.top, mPaint);
    }

    Bitmap drableToBitmap() {
        Drawable d = getResources().getDrawable(R.drawable.meizi); //xxx根据自己的情况获取drawable
        BitmapDrawable bd = (BitmapDrawable) d;
        return bd.getBitmap();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mViewWidth = getMeasuredWidth();
        mViewHeight = getMeasuredHeight();

//        rectF.set(
//                mViewWidth / 2 - mRadius,
//                mViewHeight / 2 - mRadius,
//                mViewWidth / 2 + mRadius,
//                mViewHeight / 2 + mRadius);
        rectF.set(
                0, 0,
                mViewWidth,
                mViewHeight);


    }

    public Bitmap getCroppedRoundBitmap(Bitmap bmp, int radius) {
        Bitmap scaledSrcBmp;

        //制定圆形头像的直角
        int diameter = radius * 2;

        // 为了防止宽高不相等,造成圆形图片变形,因此截取长方形中处于中间位置最大的正方形图片
        int bmpWidth = bmp.getWidth();
        int bmpHeight = bmp.getHeight();

        int squareWidth = 0, squareHeight = 0;

        int x = 0, y = 0;

        Bitmap squareBitmap;
        /**
         * 计算等比例正方向
         */
        squareBitmap = getSquareHeight(bmp, bmpWidth, bmpHeight);

        if (squareBitmap.getWidth() != diameter
                || squareBitmap.getHeight() != diameter) {
            scaledSrcBmp = Bitmap.createScaledBitmap(squareBitmap, diameter,
                    diameter, true);

        } else {
            scaledSrcBmp = squareBitmap;
        }

        /**
         * 建立一个空白图片
         */
        Bitmap output = Bitmap.createBitmap(mViewWidth * 2,
                mViewWidth * 2, Bitmap.Config.ARGB_8888);

        // TODO: 2016/6/1  canvas 进行关联  第二个canvas
        Canvas canvas = new Canvas(output);

        Rect rect = new Rect(0, 0, scaledSrcBmp.getWidth(),
                scaledSrcBmp.getHeight());

        Paint paint = new Paint();
        //抗锯齿 滤波 抗锯齿
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        paint.setColor(getResources().getColor(R.color.black));

//        canvas.drawARGB(0, 0, 0, 0);

        // TODO: 2016/6/1  圆形图层 1
        canvas.drawCircle(scaledSrcBmp.getWidth() / 2,
                scaledSrcBmp.getHeight() / 2, scaledSrcBmp.getWidth() / 2,
                paint);

        // TODO: 2016/6/1  矩形图层 1
//        canvas.drawRect(rect,paint);
//
        // todo 图层之间的关系 http://blog.csdn.net/wm111/article/details/7299294  图层关系。
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

        //todo 上层图层2
        canvas.drawBitmap(scaledSrcBmp, rect, rect, paint);

        // bitmap回收(recycle导致在布局文件XML看不到效果)
        // bmp.recycle();
        // squareBitmap.recycle();
        // scaledSrcBmp.recycle();
        bmp = null;
        squareBitmap = null;
        scaledSrcBmp = null;
        return output;
    }

    /**
     * 得到中间位置 等比例 以较小边优先
     *
     * @param bmp
     * @param bmpWidth
     * @param bmpHeight
     * @return
     */
    private Bitmap getSquareHeight(Bitmap bmp, int bmpWidth, int bmpHeight) {
        int squareHeight;
        int squareWidth;
        int x;
        int y;
        Bitmap squareBitmap;

        // todo  高大于宽
        if (bmpHeight > bmpWidth) {
            squareWidth = squareHeight = bmpWidth;
            x = 0;
            y = (bmpHeight - bmpWidth) / 2; //计算top开始位置
            // 截取正方形图片
            squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth,
                    squareHeight);
            //todo 宽大于高
        } else if (bmpHeight < bmpWidth) {
            squareWidth = squareHeight = bmpHeight;
            x = (bmpWidth - bmpHeight) / 2;
            y = 0;
            squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth,
                    squareHeight);
        } else {
            squareBitmap = bmp;
        }
        return squareBitmap;
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灯塔@kuaidao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值