使用到的知识: 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;
}
}