android矩形裁剪框
红色与青色 人气:0前阵子做视频编辑功能,视频裁剪功能不太好用,就简单的修改了一下
正常模式是这样的
简单的添加了等比例裁剪
贴代码
public class CutView extends View { float downX; float downY; boolean isLeft; boolean isRight; boolean isTop; boolean isBottom; boolean isMove; boolean isSlideLeft; boolean isSlideRight; boolean isSlideTop; boolean isSlideBottom; float rectLeft; float rectRight; float rectTop; float rectBottom; private int measuredWidth; private int measuredHeight; private Paint paint; private int dp3; private int cornerLength; private int dp1; private float aspect = -1; public CutView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public CutView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CutView(Context context) { super(context); init(); } private void init() { dp3 = (int) getResources().getDimension(R.dimen.dp3); dp1 = (int) getResources().getDimension(R.dimen.dp1); paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = event.getX(); downY = event.getY(); if(downX >= rectLeft && downX <= rectRight && downY >= rectTop && downY <= rectBottom){ //判断手指的范围在左面还是右面 int w = (int) ((rectRight - rectLeft)/3); if (downX >= rectLeft && downX <= rectLeft+w) { isLeft = true; } else if (downX <= rectRight && downX >= rectRight - w) { isRight = true; } //判断手指的范围在上面还是下面 int h = (int) ((rectBottom - rectTop)/3); if (downY >= rectTop && downY <= rectTop+h) { isTop = true; } else if (downY <= rectBottom && downY >= rectBottom - h) { isBottom = true; } //如果手指范围没有在任何边界位置, 那么我们就认为用户是想拖拽框体 if (!isLeft && !isTop && !isRight && !isBottom) { isMove = true; } } break; case MotionEvent.ACTION_MOVE: float moveX = event.getX(); float moveY = event.getY(); //得到手指移动距离 float slideX = moveX - downX ; float slideY = moveY - downY; if (isMove) {//判断是否是拖拽模式 rectLeft += slideX; rectRight += slideX; rectTop += slideY; rectBottom += slideY; //同时改变left和right值, 达到左右移动的效果 if (rectLeft < 0 || rectRight > measuredWidth) {//判断x轴的移动边界 rectLeft -= slideX; rectRight -= slideX; } //同时改变top和bottom值, 达到上下移动的效果 if (rectTop < 0 || rectBottom > measuredHeight ) {//判断y轴的移动边界 rectTop -= slideY; rectBottom -= slideY; } //实时触发onDraw()方法 invalidate(); downX = moveX; downY = moveY; } else { if(aspect != -1){ if(isLeft && (isTop || isBottom)){ if(!isSlideLeft && !isSlideTop && !isSlideBottom){ float x = Math.abs(slideX); float y = Math.abs(slideY); if(x > y && x > 10){ isSlideLeft = true; }else if(x < y && y >10){ if(isTop){ isSlideTop = true; }else{ isSlideBottom = true; } } } }else if (isRight && (isTop || isBottom)){ if(!isSlideRight && !isSlideTop && !isSlideBottom){ float x = Math.abs(slideX); float y = Math.abs(slideY); if(x > y && x > 10){ isSlideRight = true; }else if(x < y && y >10){ if(isTop){ isSlideTop = true; }else{ isSlideBottom = true; } } } }else if(isLeft && !isSlideLeft){ isSlideLeft = true; }else if(isRight && !isSlideLeft){ isSlideRight = true; }else if(isTop && !isSlideTop){ isSlideTop = true; }else if(isBottom && !isSlideBottom){ isSlideBottom = true; } if (isSlideLeft) { rectLeft += slideX; if (rectLeft < 0) rectLeft = 0; float w = rectRight - rectLeft; if(w < cornerLength * 2){ w = cornerLength * 2; rectLeft = rectRight - w; } float h = w/aspect; if(h < cornerLength * 2){ h = cornerLength * 2; w = h *aspect; rectLeft = rectRight - w; } if(isTop){ rectBottom = rectTop + h; }else if(isBottom){ rectTop = rectBottom - h; }else{ float rh = rectBottom - rectTop; float t = (rh - h)/2; rectTop += t; rectBottom -= t; } if(rectTop < 0){ rectTop = 0; rectBottom = h; if(rectBottom > measuredHeight){ rectBottom = measuredHeight; } w = rectBottom *aspect; rectLeft = rectRight - w; }else if(rectBottom > measuredHeight){ rectBottom = measuredHeight; rectTop = measuredHeight - h; if(rectTop < 0){ rectTop = 0; } w = (rectBottom - rectTop) *aspect; rectLeft = rectRight - w; } invalidate(); downX = moveX; downY = moveY; } else if (isSlideRight) { rectRight += slideX; if (rectRight > measuredWidth ) rectRight = measuredWidth; float w = rectRight - rectLeft; if(w < cornerLength * 2){ w = cornerLength * 2; rectRight = rectLeft + w; } float h = w/aspect; if(h < cornerLength * 2){ h = cornerLength * 2; w = h *aspect; rectRight = rectLeft + w; } if(isTop){ rectBottom = rectTop + h; }else if(isBottom){ rectTop = rectBottom - h; }else{ float rh = rectBottom - rectTop; float t = (rh - h)/2; rectTop += t; rectBottom -= t; } if(rectTop < 0){ rectTop = 0; rectBottom = h; if(rectBottom > measuredHeight){ rectBottom = measuredHeight; } w = rectBottom *aspect; rectRight = rectLeft + w; }else if(rectBottom > measuredHeight){ rectBottom = measuredHeight; rectTop = measuredHeight - h; if(rectTop < 0){ rectTop = 0; } w = (rectBottom - rectTop) *aspect; rectRight = rectLeft + w; } invalidate(); downX = moveX; downY = moveY; }else if (isSlideTop) { rectTop += slideY; if (rectTop < 0) rectTop = 0; float h = rectBottom - rectTop; if(h < cornerLength * 2){ h = cornerLength * 2; rectTop = rectBottom - h; } float w = h*aspect; if(w < cornerLength * 2){ w = cornerLength * 2; h = w /aspect; rectTop = rectBottom - h; } if(isLeft){ rectRight = rectLeft + w; }else if(isRight){ rectLeft = rectRight - w; }else{ float rw = rectRight - rectLeft; float t = (rw - w)/2; rectLeft += t; rectRight -= t; } if(rectLeft < 0){ rectLeft = 0; rectRight = w; if(rectRight > measuredWidth){ rectRight = measuredWidth; } h = rectRight /aspect; rectTop = rectBottom - h; }else if(rectRight > measuredWidth){ rectRight = measuredWidth; rectLeft = measuredWidth - w; if(rectLeft < 0){ rectLeft = 0; w = measuredWidth; } h = w /aspect; rectTop = rectBottom - h; } invalidate(); downX = moveX; downY = moveY; } else if (isSlideBottom) { rectBottom += slideY; if (rectBottom > measuredHeight ) rectBottom = measuredHeight ; float h = rectBottom - rectTop; if(h < cornerLength * 2){ h = cornerLength * 2; rectBottom = rectTop + h; } float w = h*aspect; if(w < cornerLength * 2){ w = cornerLength * 2; h = w /aspect; rectBottom = rectTop + h; } if(isLeft){ rectRight = rectLeft + w; }else if(isRight){ rectLeft = rectRight - w; }else{ float rw = rectRight - rectLeft; float t = (rw - w)/2; rectLeft += t; rectRight -= t; } if(rectLeft < 0){ rectLeft = 0; rectRight = w; if(rectRight > measuredWidth){ rectRight = measuredWidth; } h = rectRight /aspect; rectBottom = rectTop + h; }else if(rectRight > measuredWidth){ rectRight = measuredWidth; rectLeft = measuredWidth - w; if(rectLeft < 0){ rectLeft = 0; w = measuredWidth; } h = w /aspect; rectBottom = rectTop + h; } invalidate(); downX = moveX; downY = moveY; } }else{ if (isLeft) { rectLeft += slideX; if (rectLeft < 0) rectLeft = 0; if (rectLeft > rectRight - cornerLength * 2) rectLeft = rectRight - cornerLength * 2; } else if (isRight) { rectRight += slideX; if (rectRight > measuredWidth ) rectRight = measuredWidth; if (rectRight < rectLeft + cornerLength * 2) rectRight = rectLeft + cornerLength * 2; } //改变边框的高度, 如果两个都满足(比如手指在边角位置),那么就呈现一种缩放状态 if (isTop) { rectTop += slideY; if (rectTop < 0) rectTop = 0; if (rectTop > rectBottom - cornerLength * 2) rectTop = rectBottom - cornerLength * 2; } else if (isBottom) { rectBottom += slideY; if (rectBottom > measuredHeight ) rectBottom = measuredHeight ; if (rectBottom < rectTop + cornerLength * 2) rectBottom = rectTop + cornerLength * 2; } invalidate(); downX = moveX; downY = moveY; } } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: isLeft = false; isRight = false; isTop = false; isBottom = false; isMove = false; isSlideLeft = false; isSlideRight = false; isSlideTop = false; isSlideBottom = false; break; } return true; } /** * 得到裁剪区域的margin值 */ public float[] getCutArr() { float[] arr = new float[4]; arr[0] = rectLeft ; arr[1] = rectTop ; arr[2] = rectRight ; arr[3] = rectBottom ; return arr; } public int getRectWidth() { return (int) (measuredWidth); } public int getRectHeight() { return (int) (measuredHeight); } public void setAspect(float aspect){ this.aspect = aspect; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (measuredWidth == 0) { initParams(); } } private void initParams() { measuredWidth = getMeasuredWidth(); measuredHeight = getMeasuredHeight(); if(aspect == -1){ cornerLength = measuredWidth / 6; rectRight = measuredWidth ; rectLeft = 0; rectTop = 0; rectBottom = measuredHeight ; }else{ float vh = measuredWidth*1.0f/measuredHeight; if(aspect > 1){ cornerLength = measuredWidth / 6; }else{ cornerLength = measuredHeight / 6; } if(aspect > vh){ rectLeft = 0; rectRight = measuredWidth; float h = measuredWidth/aspect; rectTop = (measuredHeight - h)/2; rectBottom = rectTop + h; }else{ rectTop = 0; rectBottom = measuredHeight; float w = measuredHeight*aspect; rectLeft = (measuredWidth - w)/2; rectRight = rectLeft + w; } } } @Override protected void onDraw(Canvas canvas) { paint.setStrokeWidth(dp1); //绘制裁剪区域的矩形, 传入margin值来确定大小 canvas.drawRect(rectLeft, rectTop, rectRight, rectBottom, paint); //绘制四条分割线和四个角 drawLine(canvas, rectLeft, rectTop, rectRight, rectBottom); } /** * 绘制四条分割线和四个角 */ private void drawLine(Canvas canvas, float left, float top, float right, float bottom) { paint.setStrokeWidth(1); //绘制四条分割线 float startX = (right - left) / 3 + left; float startY = top; float stopX = (right - left) / 3 + left; float stopY = bottom; canvas.drawLine(startX, startY, stopX, stopY, paint); startX = (right - left) / 3 * 2 + left; startY = top; stopX = (right - left) / 3 * 2 + left; stopY = bottom; canvas.drawLine(startX, startY, stopX, stopY, paint); startX = left; startY = (bottom - top) / 3 + top; stopX = right; stopY = (bottom - top) / 3 + top; canvas.drawLine(startX, startY, stopX, stopY, paint); startX = left; startY = (bottom - top) / 3 * 2 + top; stopX = right; stopY = (bottom - top) / 3 * 2 + top; canvas.drawLine(startX, startY, stopX, stopY, paint); paint.setStrokeWidth(dp3); //绘制四个角 startX = left - dp3 / 2; startY = top; stopX = left + cornerLength; stopY = top; canvas.drawLine(startX, startY, stopX, stopY, paint); startX = left; startY = top; stopX = left; stopY = top + cornerLength; canvas.drawLine(startX, startY, stopX, stopY, paint); startX = right + dp3 / 2; startY = top; stopX = right - cornerLength; stopY = top; canvas.drawLine(startX, startY, stopX, stopY, paint); startX = right; startY = top; stopX = right; stopY = top + cornerLength; canvas.drawLine(startX, startY, stopX, stopY, paint); startX = left; startY = bottom; stopX = left; stopY = bottom - cornerLength; canvas.drawLine(startX, startY, stopX, stopY, paint); startX = left - dp3 / 2; startY = bottom; stopX = left + cornerLength; stopY = bottom; canvas.drawLine(startX, startY, stopX, stopY, paint); startX = right + dp3 / 2; startY = bottom; stopX = right - cornerLength; stopY = bottom; canvas.drawLine(startX, startY, stopX, stopY, paint); startX = right; startY = bottom; stopX = right; stopY = bottom - cornerLength; canvas.drawLine(startX, startY, stopX, stopY, paint); } }
使用的时候,只要把这个CutView盖在图片的View上,CutView的宽高必须和图片View的显示宽高一样
我是这样计算的
int screenWidth = mWidthPixels; int screenHeight = mHeightPixels; int left,top,viewWidth,viewHeight; float sh = screenWidth*1.0f/screenHeight; float vh = videoWidth *1.0f/ videoHeight; if(sh < vh){ left = 0; viewWidth = screenWidth; viewHeight = (int)(videoHeight *1.0f/ videoWidth *viewWidth); top = (screenHeight - viewHeight)/2; }else{ top = 0; viewHeight = screenHeight; viewWidth = (int)(videoWidth *1.0f/ videoHeight *viewHeight); left = (screenWidth - viewWidth)/2; } LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(viewWidth,viewHeight); params.leftMargin = left; params.topMargin = top; params.bottomMargin = mHeightPixels - top - viewHeight; videoView.setLayoutParams(params);
设置是否比例画框
cutView.setAspect(-1);
-1表示不用,需要比例显示的话就传入width*1.0f/heigh
加载全部内容