定义自定义View:
/**
* 图片裁剪自定义View
*/
public class CropImageView extends View {
private Paint mPaint;
private Bitmap mBitmap;
//裁剪框的宽高
private float mBoxWidth;
private float mBoxHeight;
//裁剪框的左上角坐标
private float mBoxX;
private float mBoxY;
//图片缩放比例
private float mScale;
//图片偏移量
private float mTranslateX;
private float mTranslateY;
private int mImageWidth;
private int mImageHeight;
//触摸点的坐标
private float mX;
private float mY;
//触摸的模式
private int mMode = 0;
public static final int DRAG = 1;
public static final int ZOOM = 2;
//触摸的两个点
private PointF mPoint1 = new PointF();
private PointF mPoint2 = new PointF();
//缩放的最小比例
private static final float SCALE_MIN = 0.5f;
//缩放的最大比例
private static final float SCALE_MAX = 1.5f;
//移动时,手指在屏幕上移动的距离
private float mMoveX;
private float mMoveY;
public CropImageView(Context context) {
this(context,null);
}
public CropImageView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public CropImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
//抗锯齿
mPaint.setAntiAlias(true);
//裁剪框的宽高
mBoxWidth = (float) ScreenUtil.getScreenWidth(getContext()) * 0.8f;
mBoxHeight = (float) ScreenUtil.getScreenHeight(getContext()) * 0.4f;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBitmap != null) {
canvas.translate(mTranslateX, mTranslateY);
canvas.scale(mScale, mScale, mBoxX + mBoxWidth / 2, mBoxY + mBoxHeight / 2);
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
//绘制裁剪框
canvas.drawRect(mBoxX, mBoxY, mBoxX + mBoxWidth, mBoxY + mBoxHeight, mPaint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//获取触摸点的坐标
mX = event.getX();
mY = event.getY();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mMode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
mMode = ZOOM;
//记录触摸的两个点的坐标
mPoint1.set(event.getX(0), event.getY(0));
mPoint2.set(event.getX(1), event.getY(1));
break;
case MotionEvent.ACTION_MOVE:
if (mMode == ZOOM) {
//计算两个触摸点的距离
float distance = (float) Math.sqrt(Math.pow(event.getX(0) - event.getX(1), 2) + Math.pow(event.getY(0) - event.getY(1), 2));
//计算缩放比例
mScale = distance / (float) Math.sqrt(Math.pow(mPoint1.x - mPoint2.x, 2) + Math.pow(mPoint1.y - mPoint2.y, 2));
mScale = Math.max(mScale, SCALE_MIN);
mScale = Math.min(mScale, SCALE_MAX);
//计算图片的偏移量
mTranslateX = mX - mImageWidth / 2 - (mX - mImageWidth / 2 - mTranslateX) * mScale / mScale;
mTranslateY = mY - mImageHeight / 2 - (mY - mImageHeight / 2 - mTranslateY) * mScale / mScale;
if (mTranslateX > 0) {
mTranslateX = 0;
} else if (mTranslateX < -(mImageWidth * mScale - mBoxWidth)) {
mTranslateX = -(mImageWidth * mScale - mBoxWidth);
}
if (mTranslateY > 0) {
mTranslateY = 0;
} else if (mTranslateY < -(mImageHeight * mScale - mBoxHeight)) {
mTranslateY = -(mImageHeight * mScale - mBoxHeight);
}
invalidate();
} else if (mMode == DRAG) {
//计算移动的距离
mMoveX = mX - mImageWidth / 2 - (mX - mImageWidth / 2 - mTranslateX);
mMoveY = mY - mImageHeight / 2 - (mY - mImageHeight / 2 - mTranslateY);
if (mMoveX > 0) {
mMoveX = 0;
} else if (mMoveX < -(mImageWidth * mScale - mBoxWidth)) {
mMoveX = -(mImageWidth * mScale - mBoxWidth);
}
if (mMoveY > 0) {
mMoveY = 0;
} else if (mMoveY < -(mImageHeight * mScale - mBoxHeight)) {
mMoveY = -(mImageHeight * mScale - mBoxHeight);
}
mTranslateX = mMoveX;
mTranslateY = mMoveY;
invalidate();
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mMode = 0;
break;
}
return true;
}
/**
* 设置图片
*/
public void setImageDrawable(Bitmap bitmap) {
if (bitmap != null) {
mBitmap = bitmap;
mImageWidth = mBitmap.getWidth();
mImageHeight = mBitmap.getHeight();
mScale = 1;
mTranslateX = 0;
mTranslateY = 0;
mBoxX = (float) ScreenUtil.getScreenWidth(getContext()) * 0.1f;
mBoxY = (float) ScreenUtil.getScreenHeight(getContext()) * 0.3f;
invalidate();
}
}
/**
* 获取裁剪图片的矩形
*/
public RectF getCropRectF() {
return new RectF(mBoxX - mTranslateX, mBoxY - mTranslateY, mBoxX + mBoxWidth - mTranslateX, mBoxY + mBoxHeight - mTranslateY);
}
}
在layout文件中添加自定义View
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.kevin.cropimageview.view.CropImageView
android:id="@+id/civ_crop"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
在代码中使用
public class MainActivity extends AppCompatActivity {
private CropImageView mCropImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCropImageView = (CropImageView) findViewById(R.id.civ_crop);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic);
mCropImageView.setImageDrawable(bitmap);
}
/**
* 点击裁剪按钮
*/
public void crop(View view) {
RectF rectF = mCropImageView.getCropRectF();
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic);
Bitmap cropBitmap = Bitmap.createBitmap(bitmap, (int) rectF.left, (int) rectF.top, (int) rectF.width(), (int) rectF.height());
mCropImageView.setImageDrawable(cropBitmap);
}
}