广告
返回顶部
首页 > 资讯 > 移动开发 >Android自定义View实现照片裁剪框与照片裁剪功能
  • 172
分享到

Android自定义View实现照片裁剪框与照片裁剪功能

viewAndroid 2022-06-06 07:06:17 172人浏览 薄情痞子
摘要

本文所需要实现的就是这样一种有逼格的效果: 右上角加了个图片框,按下确定可以裁剪正方形区域里的图片并显示在右上角。 实现思路: 1:首先需要自定义一个ZoomImageVie

本文所需要实现的就是这样一种有逼格的效果:

右上角加了个图片框,按下确定可以裁剪正方形区域里的图片并显示在右上角。

实现思路:

1:首先需要自定义一个ZoomImageView来显示我们需要的图片,这个View需要让图片能够以合适的位置展现在当前布局的图片展示区域内(合适的位置值的是:如果图片长度大于屏幕,则压缩图片长度至屏幕宽度,高度等比压缩并居中显示,如果图片高度大于屏幕,则压缩图片高度至屏幕高度,长度等比压缩并居中显示。);

2:然后需要实现这个拖动的框框,该框框实现的功能有四点:拖动、扩大缩小、触摸时显示基准线、截图。

首先是布局设计image_details.xml:


<?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" 
> 
<RelativeLayout 
android:layout_width="match_parent" 
android:layout_height="55dp" 
android:background="#323441"> 
<ImageButton 
android:id="@+id/certification_returnbtn" 
android:layout_width="55dp" 
android:layout_height="55dp" 
android:background="@android:color/transparent" 
android:padding="15dp" 
android:scaleType="fitCenter" 
android:src="@drawable/topbar_returnbtn"/> 
<TextView 
android:layout_width="wrap_content" 
android:layout_height="match_parent" 
android:layout_marginLeft="10dp" 
android:layout_toRightOf="@id/certification_returnbtn" 
android:gravity="center_vertical" 
android:text="裁剪图片" 
android:textColor="@android:color/white" 
android:textSize="20sp"/> 
<!-- <ImageButton 
android:layout_width="55dp" 
android:layout_height="55dp" 
android:layout_alignParentRight="true" 
android:layout_marginRight="10dp" 
android:background="@android:color/transparent" 
android:padding="16dp" 
android:scaleType="fitCenter" 
android:src="@drawable/ic_rotate_24dp"/>--> 
<ImageView 
android:id="@+id/testimg" 
android:layout_alignParentRight="true" 
android:layout_marginRight="10dp" 
android:layout_width="55dp" 
android:layout_height="55dp"/> 
</RelativeLayout> 
<RelativeLayout 
android:layout_width="match_parent" 
android:layout_height="0dp" 
android:layout_weight="1"> 
<com.whale.nangua.pubuliuzhaopianqiang.ZoomImageView 
android:id="@+id/zoom_image_view" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:background="#303030"/> 
<com.whale.nangua.pubuliuzhaopianqiang.ChoiceBorderView 
android:id="@+id/zoom_choiceborder_view" 
android:layout_width="match_parent" 
android:layout_height="match_parent"/> 
<Button 
android:id="@+id/image_details_subbtn" 
android:text="确定" 
android:background="@drawable/image_details_submitbtn_shape" 
android:layout_marginBottom="20dp" 
android:layout_width="180dp" 
android:layout_height="40dp" 
android:layout_alignParentBottom="true" 
android:layout_centerHorizontal="true"/> 
</RelativeLayout> 
</LinearLayout>

布局比较简单,两个View互相层叠。

自定义图片大小控制视图:ZoomImageView.java

代码注释很详细就不解释了。


package com.whale.nangua.pubuliuzhaopianqiang; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.canvas; 
import android.graphics.Matrix; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.View; 
 
public class ZoomImageView extends View { 
 
public static final int STATUS_INIT = 1; 
 
private Matrix matrix = new Matrix(); 
 
private Bitmap sourceBitmap; 
 
private int currentStatus; 
 
private int width; 
 
private int height; 
 
public ZoomImageView(Context context, AttributeSet attrs) { 
super(context, attrs); 
currentStatus = STATUS_INIT; 
} 
 
public void setImageBitmap(Bitmap bitmap) { 
sourceBitmap = bitmap; 
invalidate(); 
} 
@Override 
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
super.onLayout(changed, left, top, right, bottom); 
if (changed) { 
// 分别获取到ZoomImageView的宽度和高度 
width = getWidth(); 
height = getHeight(); 
} 
} 
 
@Override 
protected void onDraw(Canvas canvas) { 
super.onDraw(canvas); 
initBitmap(canvas); 
canvas.drawBitmap(sourceBitmap, matrix, null); 
} 
float translateY;//Y轴偏移量 
float translateX;//X轴偏移量 
 
private void initBitmap(Canvas canvas) { 
if (sourceBitmap != null) { 
matrix.reset(); //重置矩阵 
int bitmapWidth = sourceBitmap.getWidth(); //得到源图片宽 
int bitmapHeight = sourceBitmap.getHeight(); //得到源图片高 
//如果原图片大小大于控件宽高 
if (bitmapWidth > width || bitmapHeight > height) { 
//如果宽和高都比屏幕大,选择差度大的一边缩小,另一边等比缩小 
if (bitmapWidth > width && bitmapHeight > height) { 
int distanceX = Math.abs(width - bitmapWidth); 
int distanceY = Math.abs(height - bitmapHeight); 
float ratio; 
//找出差值大的一边,进行缩小 
if (distanceX >= distanceY) { 
ratio = width / (bitmapWidth * 1.0f); 
matrix.postScale(ratio, ratio); 
//此时横轴铺满,只需要对竖轴进行平移 
translateY = (height - sourceBitmap.getHeight() * ratio) / 2f; 
matrix.postTranslate(0, translateY); 
} else { 
ratio = height / (bitmapHeight * 1.0f); 
matrix.postScale(ratio, ratio); 
//此时竖轴铺满,只需要对横轴进行平移 
translateX = (width - sourceBitmap.getWidth() * ratio) / 2f; 
matrix.postTranslate(translateX, 0); //在横纵轴上进行平移 
} 
//当图片宽度大于显示宽度、图片高度小于显示宽度: 
} else if (bitmapWidth > width) { 
// 当图片宽度大于屏幕宽度时,将图片等比例压缩,使它可以完全显示出来 
float ratio = width / (bitmapWidth * 1.0f); //压缩比例 
matrix.postScale(ratio, ratio); 
translateY = (height - (bitmapHeight * ratio)) / 2f; 
// 在纵坐标方向上进行偏移,以保证图片居中显示 
matrix.postTranslate(0, translateY); 
//当图片宽度小于显示宽度、图片高度大于显示宽度: 
} else if (bitmapHeight > height) { 
// 当图片高度大于屏幕高度时,将图片等比例压缩,使它可以完全显示出来 
float ratio = height / (bitmapHeight * 1.0f); //压缩比例 
matrix.postScale(ratio, ratio); 
translateX = (width - (bitmapWidth * ratio)) / 2f; 
// 在横坐标方向上进行偏移,以保证图片居中显示 
matrix.postTranslate(translateX, 0); 
} 
} else { 
// 当图片的宽高都小于屏幕宽高时,选择差度小的一边铺满,另一边等比扩大 
//计算长和宽的差值 
int distanceX = Math.abs(width - bitmapWidth); 
int distanceY = Math.abs(height - bitmapHeight); 
float ratio; 
//找出差值小的一边,进行扩大 
if (distanceX <= distanceY) { 
ratio = width / (bitmapWidth * 1.0f); 
matrix.postScale(ratio, ratio); 
//此时横轴铺满,只需要对竖轴进行平移 
translateY = (height - sourceBitmap.getHeight() * ratio) / 2f; 
matrix.postTranslate(0, translateY); 
} else { 
ratio = height / (bitmapHeight * 1.0f); 
matrix.postScale(ratio, ratio); 
//此时竖轴铺满,只需要对横轴进行平移 
translateX = (width - sourceBitmap.getWidth() * ratio) / 2f; 
matrix.postTranslate(translateX, 0); //在横纵轴上进行平移 
} 
} 
//进行绘制 
canvas.drawBitmap(sourceBitmap, matrix, null); 
} 
} 
}

重点来了,相册选取框视图:ChoiceBorderView.java


package com.whale.nangua.pubuliuzhaopianqiang; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.View; 
import android.widget.Toast; 
 
public class ChoiceBorderView extends View { 
private int scale = (int) this.getResources().getDisplayMetrics().density; //屏幕像素密度 
private float borderHeight; //总高 
private float borderWith; //总宽 
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; //四个角的长度 
//四个点坐标 
private 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 ChoiceBorderView(Context context, AttributeSet attrs) { 
super(context, attrs); 
this.setFocusable(true); 
this.setFocusableInTouchMode(true); 
init(); 
} 
 
@Override 
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
super.onLayout(changed, left, top, right, bottom); 
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}, //右上 
}; 
} 
private void init() { 
} 
private int temp1 = (RECT_CORNER_WITH - RECT_BORDER_WITH) / 2; //长方形的粗半距 
private int temp2 = (RECT_CORNER_WITH + RECT_BORDER_WITH) / 2; //四个角的粗半距 
 
@Override 
protected void onDraw(Canvas canvas) { 
Paint paintRect = new Paint(); //初始化画笔 
//画边框的画笔 
paintRect.setColor(getResources().getColor(R.color.bordercolor)); //颜色 
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); 
//画扫描线 
if (IF_SCANNING_SHOW) { 
paintRect.setColor(Color.WHITE); 
paintRect.setStrokeWidth(1); 
paintRect.setAntiAlias(true); 
paintRect.setStyle(Paint.Style.STROKE); 
//共四根线 
//竖1 
canvas.drawLine(four_corner_coordinate_positions[0][0] + borderLength / 3, 
four_corner_coordinate_positions[0][1] + temp1, 
four_corner_coordinate_positions[2][0] + borderLength / 3, 
four_corner_coordinate_positions[2][1] - temp1, 
paintRect); 
//竖2 
canvas.drawLine(four_corner_coordinate_positions[1][0] - borderLength / 3, 
four_corner_coordinate_positions[1][1] + temp1, 
four_corner_coordinate_positions[3][0] - borderLength / 3, 
four_corner_coordinate_positions[3][1] - temp1, 
paintRect); 
//横1 
canvas.drawLine(four_corner_coordinate_positions[0][0] + temp1, 
four_corner_coordinate_positions[0][1] + borderLength / 3, 
four_corner_coordinate_positions[1][0] - temp1, 
four_corner_coordinate_positions[1][1] + borderLength / 3, 
paintRect); 
//横2 
canvas.drawLine(four_corner_coordinate_positions[2][0] + temp1, 
four_corner_coordinate_positions[2][1] - borderLength / 3, 
four_corner_coordinate_positions[3][0] - temp1, 
four_corner_coordinate_positions[3][1] - borderLength / 3, 
paintRect); 
} 
} 
private boolean IF_SCANNING_SHOW = false; 
private int lastX = 0; //上次按下的X位置 
private int lastY = 0; //上次按下的Y位置 
private int offsetX = 0; //X轴偏移量 
private int offsetY = 0; //Y轴偏移量 
static int point = -1;// 用户按下的点 
private int POINT_STATE = -1; //判断用户是缩小还是放大 0放大 1缩小 
@Override 
public boolean onTouchEvent(MotionEvent event) { 
int x = (int) event.getX(); 
int y = (int) event.getY(); 
switch (event.getAction()) { 
case MotionEvent.ACTION_DOWN: 
IF_SCANNING_SHOW = true;//显示扫描线 
if (isInTheCornerCircle(event.getX(), event.getY()) != -1) { 
//开始缩放操作 
MOVE_OR_ZOOM_STATE = false; //设置false为缩放状态 
point = isInTheCornerCircle(event.getX(), event.getY()); 
} 
lastX = x; 
lastY = y; 
invalidate(); 
break; 
case MotionEvent.ACTION_MOVE: 
offsetX = x - lastX; 
offsetY = y - lastY; 
//判断当前是扩大还是缩小操作 
judgementXandY(); 
//限定移动范围 
//移动状态:只有在移动状态下才能移动 
if (MOVE_OR_ZOOM_STATE) { 
getoffsetXandoffsetY(); 
//四个点的坐标信息也要随之改变 
for (int i = 0; i < four_corner_coordinate_positions.length; i++) { 
four_corner_coordinate_positions[i][0] += offsetX; 
four_corner_coordinate_positions[i][1] += offsetY; 
//更新回调接口 
onImageDetailsSizeChanggedl.onBorderSizeChangged( 
(int) four_corner_coordinate_positions[0][0], 
(int) four_corner_coordinate_positions[0][1], 
(int) borderLength 
); 
invalidate(); 
} 
// this.scrollBy(-offsetX, -offsetY); //这里弃用,后面改用了四点坐标移动代替背景移动 
} 
//在缩放状态下 
else { 
//按住某一个点,该点的坐标改变,其他2个点坐标跟着改变,对点坐标不变 
max = Math.abs(offsetX) >= Math.abs(offsetY) ? Math.abs(offsetX) : Math.abs(offsetY); 
//只有在扩大操作才进行边界范围判断 
if (POINT_STATE == 0) { 
getoffsetXandoffsetY(); //边界范围判断 
} 
//缩小操作时进行边界不能太小判断 
else if (POINT_STATE == 1) { 
//如果边长+max太小,直接返回 
if (borderLength - max <= RECT_CORNER_HEIGHT*2-temp2) { 
max = 0; 
} 
} 
//改变坐标 
changgeFourCoodinatePosition(point, offsetX, offsetY); 
//更新边长 
notifyNowborderLength(); 
//更新回调接口 
onImageDetailsSizeChanggedl.onBorderSizeChangged( 
(int) four_corner_coordinate_positions[0][0], 
(int) four_corner_coordinate_positions[0][1], 
(int) borderLength 
); 
invalidate(); 
} 
lastX = x; 
lastY = y; 
break; 
case MotionEvent.ACTION_UP: 
IF_SCANNING_SHOW = false; //不显示扫描线 
MOVE_OR_ZOOM_STATE = true; //回归为默认的移动状态 
invalidate(); 
break; 
} 
return true; 
} 
 
private void notifyNowborderLength() { 
float a = four_corner_coordinate_positions[0][0]; 
float b = four_corner_coordinate_positions[0][1]; 
float c = four_corner_coordinate_positions[1][0]; 
float d = four_corner_coordinate_positions[1][1]; 
float temp1 = (float) Math.pow(a - c, 2); 
float temp2 = (float) Math.pow(b - d, 2); 
borderLength = (float) Math.sqrt(temp1 + temp2); 
} 
 
private void judgementXandY() { 
switch (point) { 
case 0: 
if ((offsetX <= 0 && offsetY <= 0) || (offsetX <= 0 && offsetY >= 0)) { 
POINT_STATE = 0;//扩大 
} else { 
POINT_STATE = 1;//缩小 
} 
break; 
case 1: 
if ((offsetX >= 0 && offsetY <= 0) || (offsetX >= 0 && offsetY >= 0)) { 
POINT_STATE = 0; 
} else { 
POINT_STATE = 1; 
} 
break; 
case 2: 
if ((offsetX <= 0 && offsetY >= 0) || (offsetX <= 0 && offsetY <= 0)) { 
POINT_STATE = 0; 
} else { 
POINT_STATE = 1; 
} 
break; 
case 3: 
if ((offsetX >= 0 && offsetY >= 0) || (offsetX >= 0 && offsetY <= 0)) { 
POINT_STATE = 0; 
} else { 
POINT_STATE = 1; 
} 
break; 
} 
} 
 
private void getoffsetXandoffsetY() { 
//如果是移动状态 
if (MOVE_OR_ZOOM_STATE) { 
if ((four_corner_coordinate_positions[0][0] + offsetX <= 0) || 
(four_corner_coordinate_positions[1][0] + offsetX >= borderWith) 
) { 
offsetX = 0; 
} 
if ((four_corner_coordinate_positions[0][1] + offsetY <= 0) || 
(four_corner_coordinate_positions[2][1] + offsetY >= borderHeight) 
) { 
offsetY = 0; 
} 
} 
//如果是缩放状态 
else { 
switch (point) { 
case 0: 
if ((four_corner_coordinate_positions[0][0] - max <= 0) || 
(four_corner_coordinate_positions[0][1] - max <= 0) 
) { 
max = 0; 
} 
break; 
case 1: 
if ((four_corner_coordinate_positions[1][0] + max >= borderWith) || 
(four_corner_coordinate_positions[1][1] - max <= 0) 
) { 
max = 0; 
} 
break; 
case 2: 
if ((four_corner_coordinate_positions[2][0] - max <= 0) || 
(four_corner_coordinate_positions[2][1] + max >= borderHeight) 
) { 
max = 0; 
} 
break; 
case 3: 
if ((four_corner_coordinate_positions[3][0] + max >= borderWith) || 
(four_corner_coordinate_positions[3][1] + max >= borderHeight) 
) { 
max = 0; 
} 
break; 
} 
} 
} 
static int max; 
 
private void changgeFourCoodinatePosition(int point, int offsetX, int offsetY) { 
switch (point) { 
case 0: 
if (offsetX > 0 && offsetY < 0) { 
//变化0点的位置 suoxiao 
four_corner_coordinate_positions[0][0] += max; 
four_corner_coordinate_positions[0][1] += max; 
//变化1点的Y轴 
four_corner_coordinate_positions[1][1] += max; 
//变化2点的X轴 
four_corner_coordinate_positions[2][0] += max; 
} else if (offsetX < 0 && offsetY > 0) { 
//变化0点的位置 kuoda 
four_corner_coordinate_positions[0][0] -= max; 
four_corner_coordinate_positions[0][1] -= max; 
//变化1点的Y轴 
four_corner_coordinate_positions[1][1] -= max; 
//变化2点的X轴 
four_corner_coordinate_positions[2][0] -= max; 
} else if (offsetX < 0 && offsetY < 0) { 
//变化0点的位置 kuoda 
four_corner_coordinate_positions[0][0] -= max; 
four_corner_coordinate_positions[0][1] -= max; 
//变化1点的Y轴 
four_corner_coordinate_positions[1][1] -= max; 
//变化2点的X轴 
four_corner_coordinate_positions[2][0] -= max; 
} else if (offsetX > 0 && offsetY > 0) { 
//变化0点的位置 suoxiao 
four_corner_coordinate_positions[0][0] += max; 
four_corner_coordinate_positions[0][1] += max; 
//变化1点的Y轴 
four_corner_coordinate_positions[1][1] += max; 
//变化2点的X轴 
four_corner_coordinate_positions[2][0] += max; 
} 
break; 
case 1: 
if (offsetX > 0 && offsetY < 0) { 
//变化1点的位置 
four_corner_coordinate_positions[1][0] += max; 
four_corner_coordinate_positions[1][1] -= max; 
//变化0点的Y轴 
four_corner_coordinate_positions[0][1] -= max; 
//变化3点的X轴 
four_corner_coordinate_positions[3][0] += max; 
} else if (offsetX < 0 && offsetY > 0) { 
//变化1点的位置 
four_corner_coordinate_positions[1][0] -= max; 
four_corner_coordinate_positions[1][1] += max; 
//变化0点的Y轴 
four_corner_coordinate_positions[0][1] += max; 
//变化3点的X轴 
four_corner_coordinate_positions[3][0] -= max; 
} else if (offsetX < 0 && offsetY < 0) { 
//变化1点的位置 
four_corner_coordinate_positions[1][0] -= max; 
four_corner_coordinate_positions[1][1] += max; 
//变化0点的Y轴 
four_corner_coordinate_positions[0][1] += max; 
//变化3点的X轴 
four_corner_coordinate_positions[3][0] -= max; 
} else if (offsetX > 0 && offsetY > 0) { 
//变化1点的位置 
four_corner_coordinate_positions[1][0] += max; 
four_corner_coordinate_positions[1][1] -= max; 
//变化0点的Y轴 
four_corner_coordinate_positions[0][1] -= max; 
//变化3点的X轴 
four_corner_coordinate_positions[3][0] += max; 
} 
break; 
case 2: 
if (offsetX > 0 && offsetY < 0) { 
//变化2点的位置 suoxiao 
four_corner_coordinate_positions[2][0] += max; 
four_corner_coordinate_positions[2][1] -= max; 
//变化0点的X轴 
four_corner_coordinate_positions[0][0] += max; 
//变化3点的Y轴 
four_corner_coordinate_positions[3][1] -= max; 
} else if (offsetX < 0 && offsetY > 0) { 
//变化2点的位置 kuoda 
four_corner_coordinate_positions[2][0] -= max; 
four_corner_coordinate_positions[2][1] += max; 
//变化0点的X轴 
four_corner_coordinate_positions[0][0] -= max; 
//变化3点的Y轴 
four_corner_coordinate_positions[3][1] += max; 
} else if (offsetX < 0 && offsetY < 0) { 
//变化2点的位置 kuoda 
four_corner_coordinate_positions[2][0] -= max; 
four_corner_coordinate_positions[2][1] += max; 
//变化0点的X轴 
four_corner_coordinate_positions[0][0] -= max; 
//变化3点的Y轴 
four_corner_coordinate_positions[3][1] += max; 
} else if (offsetX > 0 && offsetY > 0) { 
//变化2点的位置 suoxiao 
four_corner_coordinate_positions[2][0] += max; 
four_corner_coordinate_positions[2][1] -= max; 
//变化0点的X轴 
four_corner_coordinate_positions[0][0] += max; 
//变化3点的Y轴 
four_corner_coordinate_positions[3][1] -= max; 
} 
break; 
case 3: 
if (offsetX > 0 && offsetY < 0) { 
//变化3点的位置 kuoda 
four_corner_coordinate_positions[3][0] += max; 
four_corner_coordinate_positions[3][1] += max; 
//变化1点的X轴 
four_corner_coordinate_positions[1][0] += max; 
//变化2点的Y轴 
four_corner_coordinate_positions[2][1] += max; 
} else if (offsetX < 0 && offsetY > 0) { 
//变化3点的位置 suoxiao 
four_corner_coordinate_positions[3][0] -= max; 
four_corner_coordinate_positions[3][1] -= max; 
//变化1点的X轴 
four_corner_coordinate_positions[1][0] -= max; 
//变化2点的Y轴 
four_corner_coordinate_positions[2][1] -= max; 
} else if (offsetX < 0 && offsetY < 0) { 
//变化3点的位置 suoxiao 
four_corner_coordinate_positions[3][0] -= max; 
four_corner_coordinate_positions[3][1] -= max; 
//变化1点的X轴 
four_corner_coordinate_positions[1][0] -= max; 
//变化2点的Y轴 
four_corner_coordinate_positions[2][1] -= max; 
} else if (offsetX > 0 && offsetY > 0) { 
//变化3点的位置 kuoda 
four_corner_coordinate_positions[3][0] += max; 
four_corner_coordinate_positions[3][1] += max; 
//变化1点的X轴 
four_corner_coordinate_positions[1][0] += max; 
//变化2点的Y轴 
four_corner_coordinate_positions[2][1] += max; 
} 
break; 
} 
} 
 
private int isInTheCornerCircle(float x, float y) { 
for (int i = 0; i < four_corner_coordinate_positions.length; i++) { 
float a = four_corner_coordinate_positions[i][0]; 
float b = four_corner_coordinate_positions[i][1]; 
float temp1 = (float) Math.pow((x - a), 2); 
float temp2 = (float) Math.pow((y - b), 2); 
if (((float) RECT_CORNER_HEIGHT) >= Math.sqrt(temp1 + temp2)) { 
return i; 
} 
} 
return -1; 
} 
public interface onImageDetailsSizeChangged { 
void onBorderSizeChangged(int x, int y, int length); 
} 
public onImageDetailsSizeChangged onImageDetailsSizeChanggedl; 
public void setonImageDetailsSizeChangged(onImageDetailsSizeChangged onImageDetailsSizeChangged) { 
this.onImageDetailsSizeChanggedl = onImageDetailsSizeChangged; 
} 
} 

以上所述是小编给大家介绍的Android自定义View实现照片裁剪框与照片裁剪功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程网网站的支持!

您可能感兴趣的文章:Android 自定义View的使用介绍Android自定义View实现广告信息上下滚动效果Android自定义View实现带数字的进度条实例代码Android自定义View之自定义评价打分控件RatingBar实现自定义星星大小和间距Android自定义view制作绚丽的验证码Android自定义View实现折线图效果Android自定义View之酷炫数字圆环Android 自定义View实现单击和双击事件的方法Android自定义View之继承TextView绘制背景Android自定义view实现阻尼效果的加载动画Android自定义View实现拖动选择按钮Android实现在xml文件中引用自定义View的方法分析


--结束END--

本文标题: Android自定义View实现照片裁剪框与照片裁剪功能

本文链接: https://www.lsjlt.com/news/24506.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android自定义View实现照片裁剪框与照片裁剪功能
    本文所需要实现的就是这样一种有逼格的效果: 右上角加了个图片框,按下确定可以裁剪正方形区域里的图片并显示在右上角。 实现思路: 1:首先需要自定义一个ZoomImageVie...
    99+
    2022-06-06
    view Android
  • Android实现裁剪照片功能
    本文实例为大家分享了Android实现裁剪照片功能的具体代码,供大家参考,具体内容如下 1.   从相册选择照片进行裁剪 从相册选择照片并裁剪: private void...
    99+
    2022-11-13
  • Android如何实现裁剪照片功能
    这篇文章主要介绍Android如何实现裁剪照片功能,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!   从相册选择照片进行裁剪从相册选择照片并裁剪:private void cropFromGallery()...
    99+
    2023-06-29
  • Android实现拍照、选择图片并裁剪图片功能
    一、 实现拍照、选择图片并裁剪图片效果 按照之前博客的风格,首先看下实现效果。      二、 uCrop项目应用 想起之前看到的Yalant...
    99+
    2022-06-06
    选择 图片 Android
  • Android如何实现拍照及图片裁剪
    这篇文章主要介绍Android如何实现拍照及图片裁剪,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!最近做项目中涉及到了图片相关功能 ,在使用安卓6.0手机及7.1手机拍照时,遇到了因权限及文件管理导致程序崩溃等问题。...
    99+
    2023-05-30
    android6.0
  • Android实现拍照、选择相册图片并裁剪功能
    通过拍照或相册中获取图片,并进行裁剪操作,然后把图片显示到ImageView上。  当然也可以上传到服务器(项目中绝大部分情况是上传到服务器),参考网上资料及结合项目...
    99+
    2022-06-06
    选择 图片 Android
  • Android编程实现图片拍照剪裁的方法
    本文实例讲述了Android实现图片拍照剪裁的方法。分享给大家供大家参考,具体如下: 调用系统的裁剪工具对相册或者拍照的图片进行裁剪。 startActivityforResu...
    99+
    2022-06-06
    方法 图片 Android
  • Android图片裁剪功能实现代码
    在Android应用中,图片裁剪也是一个经常用到的功能。Android系统中可以用隐式意图调用系统应用进行裁剪,但是这样做在不同的手机可能表现出不同的效果,甚至在某些奇葩手机上...
    99+
    2022-06-06
    Android
  • Python实现图片自定义裁剪小工具
    目录前言环境依赖代码验证一下前言 本文提供将图片按照自定义尺寸进行裁剪的工具方法,一如既往的实用主义。 环境依赖 ffmpeg环境安装,可以参考:在Windows上安装FFmpeg程...
    99+
    2022-11-13
  • Android ImageView实现图片裁剪和显示功能
    首先在layout布局中设置按钮和一个ImageView <Button android:id="@+id/selectimagebtn" android:la...
    99+
    2022-06-06
    图片 Android
  • Java实现视频自定义裁剪功能
    目录前言Maven依赖代码验证一下前言 本文提供将视频按照自定义尺寸进行裁剪的Java工具类,一如既往的实用主义。 Maven依赖 <dependency>...
    99+
    2022-11-13
  • android完美实现 拍照 选择图片 剪裁等代码分享
    前言,版本兼容问题主要是由于4.4以前和4.4以后的Uri的格式不同所造成的错误 1.拍照 和选择图片   ①选择图片 intent = new Intent...
    99+
    2022-06-06
    选择 图片 Android
  • Android实现相机拍摄、选择、图片裁剪功能
    最近的一些学习心得: 功能实现:点击圆形头像之后可以实现相册上传或者开启相机,然后把得到的图片经过剪裁,把剪裁过的图片设置为头像的背景图 步骤:第一步:自定义一个类,继承Ima...
    99+
    2022-06-06
    选择 图片 相机 Android
  • Java怎么实现视频自定义裁剪功能
    今天就跟大家聊聊有关Java怎么实现视频自定义裁剪功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。前言下面提供将视频按照自定义尺寸进行裁剪的Java工具类,一如既往的实用主义。Ma...
    99+
    2023-06-28
  • Android编程实现调用系统图库与裁剪图片功能
    本文实例讲述了Android编程实现调用系统图库与裁剪图片功能。分享给大家供大家参考,具体如下: 在Android开发中,调用系统图库和裁剪照片是很常见的需求。相对于自己实现这...
    99+
    2022-06-06
    调用 图片 系统 Android
  • 使用Java代码在Android中实现图片裁剪功能
    前言 Android应用中经常会遇到上传相册图片的需求,这里记录一下如何进行相册图片的选取和裁剪。 相册选取图片 1. 激活相册或是文件管理器,来获取相片,代码如下: pr...
    99+
    2022-06-06
    用java JAVA 图片 Android
  • 如何使用Python实现图片自定义裁剪小工具
    这篇文章主要介绍了如何使用Python实现图片自定义裁剪小工具,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。环境依赖ffmpy安装:pip install ...
    99+
    2023-06-28
  • thinkphp框架中的图片旋转裁剪功能怎么实现
    这篇文章主要讲解了“thinkphp框架中的图片旋转裁剪功能怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“thinkphp框架中的图片旋转裁剪功能怎么实现”吧!第一步:安装think...
    99+
    2023-07-06
  • Android实现从本地图库/相机拍照后裁剪图片并设置头像
    玩qq或者是微信的盆友都知道,这些聊天工具里都要设置头像,一般情况下大家的解决办法是从本地图库选择图片或是从相机拍照,然后根据自己的喜爱截取图片。上述过程已经实现好了,最后一步...
    99+
    2022-06-06
    图片 地图 相机 Android
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作