原创文章——转载请注明
之前的图片裁剪功能是4点控制的,来源为他人的博客。目前有点时间,将其扩展为8控制点裁剪。
先看一下效果:
关键在于控制点的绘制,触屏时控制点的判断(一定半径的圆形范围),扩大缩小的判断,缩小的最小量判断(四角的点用对角线,中间点用长宽),移动边界越界的判断,放大缩小时控制点的重绘。
代码很简单,注释也充足,就不多解释了,上代码
public class ChoiceMatrixView extends View {
private static final String TAG = "ChoiceMatrixView";
private int scale = (int) this.getResources().getDisplayMetrics().density; //屏幕像素密度
private float borderHeight; //总高
private float borderWith; //总宽
private float imageHeight; //图片高度
private float imageWidth; //图片宽度
private float imageTranslateX; //由于图片是居中的,需要考虑x和y方向的偏移量
private float imageTranslateY; //由于图片是居中的,需要考虑x和y方向的偏移量
private float borderLength = 200 * scale; //边框长度
private int RECT_BORDER_WITH = 3 * scale; //长方形框框粗
private int RECT_CORNER_WITH = 6 * scale; //四个角的粗
private int RECT_CORNER_HEIGHT = 20 * scale; //四个角的长度
//四个点坐标
public static float[][] four_corner_coordinate_positions;
private static int NOW_MOVE_STATE = 1; //移动状态,默认为1,Y轴=1,X轴=2
private static boolean MOVE_OR_ZOOM_STATE = true; //移动或缩放状态, true 为移动
public ChoiceMatrixView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setFocusable(true);
this.setFocusableInTouchMode(true);
init();
}
/**
* 初始化布局
* @param changed
* @param left
* @param top
* @param right
* @param bottom
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
//总高和总宽需要综合考虑view的宽和高和图片的宽和高
//但是由于异步机制,无法在onLayout之前获得偏移量,因此图片溢出改为消息提醒
/*
if(imageHeight==0){
borderHeight = this.getHeight();
}else{
if(imageHeight<this.getHeight())
borderHeight=imageHeight;
else
borderHeight = this.getHeight()+getTranslationY();
}
if(imageWidth==0){
borderWith = this.getWidth();
}else{
if(imageWidth<this.getWidth())
borderWith=imageWidth;
else
borderWith = this.getWidth()+getTranslationX();
}
*/
borderHeight = this.getHeight();
borderWith = this.getWidth();
//初始化四个点的坐标
four_corner_coordinate_positions = new float[][]{
{(borderWith - borderLength) / 2, (borderHeight - borderLength) / 2}, //左上
{(borderWith + borderLength) / 2, (borderHeight - borderLength) / 2}, //右上
{(borderWith - borderLength) / 2, (borderHeight + borderLength) / 2}, //左下
{(borderWith + borderLength) / 2, (borderHeight + borderLength) / 2}, //右上
{(borderWith - borderLength) / 2 + borderLength / 2, (borderHeight - borderLength) / 2}, //上中
{(borderWith + borderLength) / 2, (borderHeight - borderLength) / 2 + borderLength / 2}, //右中
{(borderWith - borderLength) / 2, (borderHeight - borderLength) / 2 + borderLength / 2}, //左中
{(borderWith - borderLength) / 2 + borderLength / 2, (borderHeight + borderLength) / 2} //下中
};
}
private int temp1 = (RECT_CORNER_WITH - RECT_BORDER_WITH) / 2; //长方形的粗半距
private int temp2 = (RECT_CORNER_WITH + RECT_BORDER_WITH) / 2; //四个角的粗半距
/**
* RECT_CORNER_WITH = 6
* RECT_BORDER_WITH =3
*
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
Paint paintRect = new Paint(); //初始化画笔
//画边框的画笔
paintRect.setColor(getResources().getColor(R.color.darker_gray)); //颜色
paintRect.setStrokeWidth(RECT_BORDER_WITH); //宽度
paintRect.setAntiAlias(true); //抗锯齿
paintRect.setStyle(Paint.Style.STROKE); //设置空心
canvas.drawRect(four_corner_coordinate_positions[0][0],
four_corner_coordinate_positions[0][1],
four_corner_coordinate_positions[3][0],
four_corner_coordinate_positions[3][1], paintRect);
//画四个角的画笔
paintRect.setColor(Color.WHITE);
paintRect.setStrokeWidth(RECT_CORNER_WITH);
paintRect.setAntiAlias(true);
//左上角的两根
canvas.drawLine(four_corner_coordinate_positions[0][0] - temp2,
four_corner_coordinate_positions[0][1] - temp1,
four_corner_coordinate_positions[0][0] - temp1 + RECT_CORNER_HEIGHT,
four_corner_coordinate_positions[0][1] - temp1,
paintRect);
canvas.drawLine(four_corner_coordinate_positions[0][0] - temp1,
four_corner_coordinate_positions[0][1] - temp2,
four_corner_coordinate_positions[0][0] - temp1,
four_corner_coordinate_positions[0][1] - temp1 + RECT_CORNER_HEIGHT,
paintRect);
//左下角的两根
canvas.drawLine(four_corner_coordinate_positions[2][0] - temp2,
four_corner_coordinate_positions[2][1] + temp1,
four_corner_coordinate_positions[2][0] - temp1 + RECT_CORNER_HEIGHT,
four_corner_coordinate_positions[2][1] + temp1,
paintRect);
canvas.drawLine(four_corner_coordinate_positions[2][0] - temp1,
four_corner_coordinate_positions[2][1] + temp1,
four_corner_coordinate_positions[2][0] - temp1,
four_corner_coordinate_positions[2][1] + temp1 - RECT_CORNER_HEIGHT,
paintRect);
//右上角的两根
canvas.drawLine(four_corner_coordinate_positions[1][0] + temp1,
four_corner_coordinate_positions[1][1] - temp1,
four_corner_coordinate_positions[1][0] + temp1 - RECT_CORNER_HEIGHT,
four_corner_coordinate_positions[1][1] - temp1,
paintRect);
canvas.drawLine(four_corner_coordinate_positions[1][0] + temp1,
four_corner_coordinate_positions[1][1] - temp2,
four_corner_coordinate_positions[1][0] + temp1,
four_corner_coordinate_positions[1][1] - temp1 + RECT_CORNER_HEIGHT
, paintRect);
//右下角的两根
canvas.drawLine(four_corner_coordinate_positions[3][0] + temp2,
four_corner_coordinate_positions[3][1] + temp1,
four_corner_coordinate_positions[3][0] + temp1 - RECT_CORNER_HEIGHT,
four_corner_coordinate_positions[3][1] + temp1,
paintRect);
canvas.drawLine(four_corner_coordinate_positions[3][0] + temp1,
four_corner_coordinate_positions[3][1] + temp1,
four_corner_coordinate_positions[3][0] + temp1,
four_corner_coordinate_positions[3][1] + temp1 - RECT_CORNER_HEIGHT,
paintRect);
//上中
canvas.drawLine(four_corner_coordinate_positions[4][0]- temp2 - RECT_CORNER_HEIGHT,
four_corner_coordinate_positions[0][1] - temp1,
four_corner_coordinate_positions[4][0] + (temp1 + RECT_CORNER_HEIGHT),
four_corner_coordinate_positions[0][1] - temp1,
paintRect);
//右中
canvas.drawLine(four_corner_coordinate_positions[3][0],
four_corner_coordinate_positions[6][1] - temp2 - RECT_CORNER_HEIGHT,
four_corner_coordinate_positions[3][0],
four_corner_coordinate_positions[6][1] + temp1 + RECT_CORNER_HEIGHT,
paintRect);
//左中
canvas.drawLine(four_corner_coordinate_positions[0][0],
four_corner_coordinate_positions[6][1] - temp2 - RECT_CORNER_HEIGHT,
four_corner_coordinate_positions[0][0],
four_corner_coordinate_positions[6][1] + temp1 + RECT_CORNER_HEIGHT,
paintRect);
//下中
canvas.drawLine(four_corner_coordinate_positions[4][0] - temp2 - RECT_CORNER_HEIGHT,
four_corner_coordinate_positions[3][1] + temp1,
four_corner_coordinate_positions[4][0] + temp1 + RECT_CORNER_HEIGHT,
four_corner_c