代码注释很多,简单说下思路,然后直接贴代码
1、截取选定图片中间区域(宽等于高的正方形)
2、按照控件大小进行缩放
3、画圆,设置paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
4、画图
package com.dyk.thebest.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.widget.ImageView; /** * 自定义圆形图片 * <p> * 在<u><font color="#0000ff">onMeasure()</font></u>中强制设置控件的宽高一致 <br/> * 在<u><font color="#0000ff">getCroppedBitmap()</font></u>中截取图片中间区域并返回一个bitmap对象 * * @author 一口仨馍 * */ public class RoundImageView extends ImageView { public RoundImageView(Context context, AttributeSet attrs) { super(context, attrs); } public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 强制设置圆形图片控件的宽高一致 int min = Math.min(getMeasuredWidth(), getMeasuredHeight()); setMeasuredDimension(min, min); } @Override protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (drawable == null) { return; } if (getWidth() == 0 || getHeight() == 0) { return; } // 注意:此条语句不能智能提示,只能手动输入 Bitmap b = ((BitmapDrawable) drawable).getBitmap(); if (null == b) { return; } Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true); // 因为后来在onMeasure中强制设置了控件宽高相等,所以相当于下面的w强制等于h // min == w == h == sbmp.getWidth() == sbmp.getHeight()是成立的 int w = getWidth(), h = getHeight(); int min = Math.min(w, h); Bitmap roundBitmap = getCroppedBitmap(bitmap, min); canvas.drawBitmap(roundBitmap, 0, 0, null); } /** * 截取bmp中间区域的图像,并缩放至与视图宽高大小一致。画图。 * * @param bmp * Bitmap对象 * @param min * 视图宽高的最小值,单位:px * @return bitmap */ public static Bitmap getCroppedBitmap(Bitmap bmp, int min) { // 截取后的bitmap Bitmap squareBitmap; int bmpWidth = bmp.getWidth(); int bmpHeight = bmp.getHeight(); int squareWidth = 0, squareHeight = 0; int x = 0, y = 0; if (bmpHeight > bmpWidth) {// 高大于宽 squareWidth = squareHeight = bmpWidth; x = 0; y = (bmpHeight - bmpWidth) / 2; // 截取正方形图片 squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth, squareHeight); } else if (bmpHeight < bmpWidth) {// 宽大于高 squareWidth = squareHeight = bmpHeight; x = (bmpWidth - bmpHeight) / 2; y = 0; squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth, squareHeight); } else { squareBitmap = bmp; } Bitmap sbmp; //对截取后的squareBitmap缩放至控件宽高 if (squareBitmap.getWidth() != min || squareBitmap.getHeight() != min) { sbmp = Bitmap.createScaledBitmap(squareBitmap, min, min, false); } else { sbmp = squareBitmap; } Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final Paint paint = new Paint(); //指定抠图/画图区域 final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight()); paint.setAntiAlias(true); paint.setFilterBitmap(true); paint.setDither(true); canvas.drawARGB(0, 0, 0, 0);//将内容以外的区域设置为完全透明的黑色 paint.setColor(Color.parseColor("#BAB399")); canvas.drawCircle(sbmp.getWidth() / 2 + 0.7f, sbmp.getHeight() / 2 + 0.7f, min / 2 + 0.1f, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(sbmp, rect, rect, paint); return output; } }