本文实例为大家分享了android实现矩形裁剪框的具体代码,供大家参考,具体内容如下
前阵子做视频编辑功能,视频裁剪功能不太好用,就简单的修改了一下
正常模式是这样的
简单的添加了等比例裁剪
贴代码
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;
}
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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。