diff --git a/.idea/misc.xml b/.idea/misc.xml index 99202cc..c0f68ed 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -25,7 +25,7 @@ - + diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index fad720d..2a95559 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -32,17 +32,18 @@ app:cv_outer_bg_color="@color/black_alpha_160" app:cv_scan_line_color="@color/white" app:cv_scan_line_width="1dp" - app:cv_border_length="247dp" + app:cv_border_length="100dp" app:cv_border_line_width="1dp" app:cv_corner_line_with="3dp" app:cv_corner_line_height="13dp" - app:cv_min_border_length="100dp" - app:cv_crop_model="oval" + app:cv_min_border_length="45dp" + app:cv_crop_model="circle" app:cv_is_show_corner_line="true" app:cv_is_show_border_line="true" app:cv_is_show_middle_line="true" app:cv_is_show_scan_line="false" app:cv_is_touch_corner_line_scale="true" - app:cv_is_touch_middle_line_scale="true"/> + app:cv_is_touch_middle_line_scale="true" + /> \ No newline at end of file diff --git a/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/utils/BitmapUtils.java b/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/utils/BitmapUtils.java index e571fb6..57fcd9e 100644 --- a/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/utils/BitmapUtils.java +++ b/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/utils/BitmapUtils.java @@ -62,7 +62,7 @@ public static Bitmap getCropPicture(Bitmap bitmap, float preWidth, float preHeig */ public static Bitmap getCircularBitmap(Bitmap square) { if (square == null) return null; - Bitmap output = Bitmap.createBitmap(square.getWidth(), square.getHeight(), Bitmap.Config.ARGB_8888); + Bitmap output = Bitmap.createBitmap(square.getWidth(), square.getHeight(), Bitmap.Config.ARGB_4444); final Rect rect = new Rect(0, 0, square.getWidth(), square.getHeight()); Canvas canvas = new Canvas(output); @@ -86,7 +86,7 @@ public static Bitmap getCircularBitmap(Bitmap square) { */ public static Bitmap getOvalBitmap(Bitmap square) { if (square == null) return null; - Bitmap output = Bitmap.createBitmap(square.getWidth(), square.getHeight(), Bitmap.Config.ARGB_8888); + Bitmap output = Bitmap.createBitmap(square.getWidth(), square.getHeight(), Bitmap.Config.ARGB_4444); final Rect rect = new Rect(0, 0, square.getWidth(), square.getHeight()); Canvas canvas = new Canvas(output); diff --git a/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/utils/QLHUtils.java b/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/utils/QLHUtils.java index fae1383..fb1758b 100644 --- a/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/utils/QLHUtils.java +++ b/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/utils/QLHUtils.java @@ -1,6 +1,11 @@ package com.qlh.crop.cropviewlibrary.utils; +import android.content.Context; +import android.graphics.Point; +import android.os.Build; +import android.view.WindowManager; + import java.util.Arrays; import java.util.List; @@ -280,4 +285,49 @@ public static void changePositions(int point, int offsetX, int offsetY, float[][ break; } } + + /** + * 判断字符串是否为空,即为null或"" + */ + public static boolean isEmpty(String str) { + return ((str == null) || (str.length() == 0) || "null".equals(str)); + } + + /** + * Return the width of screen, in pixel. + * + * @return the width of screen, in pixel + */ + public static int getScreenWidth(Context context) { + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + if (wm == null) { + return context.getResources().getDisplayMetrics().widthPixels; + } + Point point = new Point(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + wm.getDefaultDisplay().getRealSize(point); + } else { + wm.getDefaultDisplay().getSize(point); + } + return point.x; + } + + /** + * Return the height of screen, in pixel. + * + * @return the height of screen, in pixel + */ + public static int getScreenHeight(Context context) { + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + if (wm == null) { + return context.getResources().getDisplayMetrics().heightPixels; + } + Point point = new Point(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + wm.getDefaultDisplay().getRealSize(point); + } else { + wm.getDefaultDisplay().getSize(point); + } + return point.y; + } } diff --git a/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/view/CropView.java b/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/view/CropView.java index 60353aa..a66cae3 100644 --- a/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/view/CropView.java +++ b/cropviewlibrary/src/main/java/com/qlh/crop/cropviewlibrary/view/CropView.java @@ -9,8 +9,8 @@ import android.graphics.Path; import android.graphics.RectF; import android.graphics.Region; +import android.os.Message; import android.util.AttributeSet; -import android.util.Log; import android.view.MotionEvent; import android.view.View; @@ -24,8 +24,8 @@ * 作者:dell on 2018/9/7 18:26 * 描述:绘制拍照推荐裁剪框 *
- * 本库目前只是简单的绘制和裁剪 - *
+ * 本库目前只是简单的绘制和裁剪 + *
*/ public class CropView extends View { @@ -36,15 +36,16 @@ public class CropView extends View { static int max; private static int NOW_MOVE_STATE = 1; //移动状态,默认为1,Y轴=1,X轴=2 private static boolean MOVE_OR_ZOOM_STATE = true; //移动或缩放状态, true 为移动 - private float VIEW_HEIGHT; //总高 - private float VIEW_WIDTH; //总宽 + private int VIEW_HEIGHT; //视图高 + private int VIEW_WIDTH; //视图宽 + private String VIEW_WIDTH_PERCENT, VIEW_HEIGHT_PERCENT;//视图宽高占屏幕比例 //单位dp - private float BORDER_LENGTH = 200; //边框长度 + private int BORDER_LENGTH = 200; //边框长度 private int RECT_BORDER_WITH = 3; //长方形框框粗 private int RECT_CORNER_WITH = 6; //四个角的粗 private int RECT_CORNER_HEIGHT = 20; //四个角的长度 - private int MIN_BORDER_LENGTH = RECT_CORNER_HEIGHT*3;//最小边框长度 + private int MIN_BORDER_LENGTH = RECT_CORNER_HEIGHT * 5;//最小边框长度 private int CROP_MODE = CropMode.RECT.getId();//裁剪模式 //显示控制 @@ -117,21 +118,24 @@ private void handleStyleable(Context context, AttributeSet attrs, int defStyle, (int) (mDensity * BORDER_LENGTH)); MIN_BORDER_LENGTH = ta.getDimensionPixelSize(R.styleable.CropView_cv_min_border_length, - (RECT_CORNER_HEIGHT*3)); + (RECT_CORNER_HEIGHT * 5)); //设置最小值 - if (MIN_BORDER_LENGTH QLHUtils.getScreenWidth(getContext()) + ? QLHUtils.getScreenWidth(getContext()) + : value * QLHUtils.getScreenWidth(getContext())/100; + } + if ("h".equals(reference)){ + widthSize = value * QLHUtils.getScreenHeight(getContext())/100 > QLHUtils.getScreenHeight(getContext()) + ? QLHUtils.getScreenHeight(getContext()) + : value * QLHUtils.getScreenHeight(getContext())/100; + } + } + } + + if (heightMode == MeasureSpec.EXACTLY && heightSize == 0){ + if (!QLHUtils.isEmpty(VIEW_HEIGHT_PERCENT) && VIEW_HEIGHT_PERCENT.matches(reg)) { + String[] heights = VIEW_HEIGHT_PERCENT.split("%"); + //获取数值 + int value = Integer.valueOf(heights[0]); + //获取参考系 + String reference = heights[1]; + if ("w".equals(reference)) {//参考宽度 + heightSize = value * QLHUtils.getScreenWidth(getContext())/100 > QLHUtils.getScreenWidth(getContext()) + ? QLHUtils.getScreenWidth(getContext()) + : value * QLHUtils.getScreenWidth(getContext())/100; + } + if ("h".equals(reference)){ + heightSize = value * QLHUtils.getScreenHeight(getContext())/100 > QLHUtils.getScreenHeight(getContext()) + ? QLHUtils.getScreenHeight(getContext()) + : value * QLHUtils.getScreenHeight(getContext())/100; + } + } } + + //最后不要忘记了,调用父类的测量方法 + setMeasuredDimension(widthSize, heightSize); } - /**矩形裁剪模式**/ - private void drawRect(Canvas canvas){ + /** + * 验证裁剪框的尺寸是否超出视图范围 + * **/ + + private void validateSize(){ + if (BORDER_LENGTH=Math.min(VIEW_WIDTH,VIEW_HEIGHT)){ + BORDER_LENGTH = Math.min(VIEW_WIDTH,VIEW_HEIGHT)-RECT_CORNER_HEIGHT*3; + //MIN_BORDER_LENGTH = BORDER_LENGTH; + } + if (RECT_CORNER_HEIGHT*3>=BORDER_LENGTH){ + RECT_CORNER_HEIGHT = (int) (BORDER_LENGTH/5); + } + + } + + /** + * 矩形裁剪模式 + **/ + private void drawRect(Canvas canvas) { //先绘制黑色透明度背景 drawAlphaBg(canvas); //矩形框 - if (BORDER_SHOW){ - drawBorderRect(canvas); - } + if (BORDER_SHOW) { + drawBorderRect(canvas); + } //四个拐角线 - if (CORNER_SHOW){ - drawCornerLine(canvas); - } + if (CORNER_SHOW) { + drawCornerLine(canvas); + } //四个中间线 - if (MIDDLE_SHOW){ + if (MIDDLE_SHOW) { drawMiddleLine(canvas); } //画扫描线 @@ -313,41 +393,46 @@ private void drawRect(Canvas canvas){ } } - /**圆形裁剪模式**/ - private void drawCircle(Canvas canvas){ + /** + * 矩形裁剪模式 + **/ + private void drawOval(Canvas canvas) { //圆形裁剪框 - drawCircleUsePath(canvas); + drawOvalUsePath(canvas); + //绘制矩形框 + if (BORDER_SHOW) { + drawBorderRect(canvas); + } //四个拐角线 - if (CORNER_SHOW){ - drawCornerLine(canvas); - } - //四个横线 - if (MIDDLE_SHOW){ + if (CORNER_SHOW) { + drawCornerLine(canvas); + } + //四个中间线 + if (MIDDLE_SHOW) { drawMiddleLine(canvas); } } - /**矩形裁剪模式**/ - private void drawOval(Canvas canvas){ + /** + * 圆形裁剪模式 + **/ + private void drawCircle(Canvas canvas) { //圆形裁剪框 - drawOvalUsePath(canvas); - //绘制矩形框 - if (BORDER_SHOW){ - drawBorderRect(canvas); - } + drawCircleUsePath(canvas); //四个拐角线 - if (CORNER_SHOW){ + if (CORNER_SHOW) { drawCornerLine(canvas); } - //四个中间线 - if (MIDDLE_SHOW){ - drawMiddleLine(canvas); - } + //四个横线 + if (MIDDLE_SHOW) { + drawMiddleLine(canvas); + } } //-----------------------------------------绘制方法START----------------------------------------// + /** * 绘制黑色半透明背景 * 根据四个角的坐标范围,绘制多个矩形拼接 @@ -523,9 +608,9 @@ private void drawScanLine(Canvas canvas) { paintRect.setStyle(Paint.Style.STROKE); //共四根线 //竖1 - canvas.drawLine((four_corner_coordinate_positions[0][0] +four_corner_coordinate_positions[4][0])/2 , + canvas.drawLine((four_corner_coordinate_positions[0][0] + four_corner_coordinate_positions[4][0]) / 2, four_corner_coordinate_positions[0][1], - (four_corner_coordinate_positions[0][0] +four_corner_coordinate_positions[4][0])/2, + (four_corner_coordinate_positions[0][0] + four_corner_coordinate_positions[4][0]) / 2, four_corner_coordinate_positions[2][1], paintRect); //竖2 @@ -535,16 +620,16 @@ private void drawScanLine(Canvas canvas) { four_corner_coordinate_positions[7][1], paintRect); //竖3 - canvas.drawLine( (four_corner_coordinate_positions[1][0]+four_corner_coordinate_positions[4][0])/2, + canvas.drawLine((four_corner_coordinate_positions[1][0] + four_corner_coordinate_positions[4][0]) / 2, four_corner_coordinate_positions[1][1], - (four_corner_coordinate_positions[1][0]+four_corner_coordinate_positions[4][0])/2, + (four_corner_coordinate_positions[1][0] + four_corner_coordinate_positions[4][0]) / 2, four_corner_coordinate_positions[3][1], paintRect); //横1 - canvas.drawLine(four_corner_coordinate_positions[0][0] , - (four_corner_coordinate_positions[0][1]+four_corner_coordinate_positions[6][1])/2, + canvas.drawLine(four_corner_coordinate_positions[0][0], + (four_corner_coordinate_positions[0][1] + four_corner_coordinate_positions[6][1]) / 2, four_corner_coordinate_positions[1][0], - (four_corner_coordinate_positions[0][1]+four_corner_coordinate_positions[6][1])/2, + (four_corner_coordinate_positions[0][1] + four_corner_coordinate_positions[6][1]) / 2, paintRect); //横2 canvas.drawLine(four_corner_coordinate_positions[6][0], @@ -553,32 +638,34 @@ private void drawScanLine(Canvas canvas) { four_corner_coordinate_positions[5][1], paintRect); //横3 - canvas.drawLine(four_corner_coordinate_positions[0][0] , - (four_corner_coordinate_positions[2][1]+four_corner_coordinate_positions[6][1])/2, + canvas.drawLine(four_corner_coordinate_positions[0][0], + (four_corner_coordinate_positions[2][1] + four_corner_coordinate_positions[6][1]) / 2, four_corner_coordinate_positions[1][0], - (four_corner_coordinate_positions[2][1]+four_corner_coordinate_positions[6][1])/2, + (four_corner_coordinate_positions[2][1] + four_corner_coordinate_positions[6][1]) / 2, paintRect); paintRect.reset(); } /** - * 绘制圆形(路径剪切法) + * 绘制椭圆(路径剪切法) * 如果是几何形的预览框, * 那么首推限制绘画区域的方案, * 内存占用率低。 **/ - private void drawCircleUsePath(Canvas canvas) { + private void drawOvalUsePath(Canvas canvas) { Paint paint = new Paint(); paint.setColor(Color.TRANSPARENT); paint.setStyle(Paint.Style.FILL); paint.setAntiAlias(true); //创建圆形预览框 Path path = new Path(); - path.addCircle( - (four_corner_coordinate_positions[0][0] + four_corner_coordinate_positions[1][0]) / 2, - (four_corner_coordinate_positions[0][1] + four_corner_coordinate_positions[2][1]) / 2, - BORDER_LENGTH / 2, + path.addOval(new RectF( + four_corner_coordinate_positions[0][0], + four_corner_coordinate_positions[0][1], + four_corner_coordinate_positions[1][0], + four_corner_coordinate_positions[2][1] + ), Path.Direction.CW); //保存当前canvas 状态 canvas.save(); @@ -592,24 +679,22 @@ private void drawCircleUsePath(Canvas canvas) { } /** - * 绘制椭圆(路径剪切法) + * 绘制圆形(路径剪切法) * 如果是几何形的预览框, * 那么首推限制绘画区域的方案, * 内存占用率低。 **/ - private void drawOvalUsePath(Canvas canvas) { + private void drawCircleUsePath(Canvas canvas) { Paint paint = new Paint(); paint.setColor(Color.TRANSPARENT); paint.setStyle(Paint.Style.FILL); paint.setAntiAlias(true); //创建圆形预览框 Path path = new Path(); - path.addOval(new RectF( - four_corner_coordinate_positions[0][0], - four_corner_coordinate_positions[0][1], - four_corner_coordinate_positions[1][0], - four_corner_coordinate_positions[2][1] - ), + path.addCircle( + (four_corner_coordinate_positions[0][0] + four_corner_coordinate_positions[1][0]) / 2, + (four_corner_coordinate_positions[0][1] + four_corner_coordinate_positions[2][1]) / 2, + BORDER_LENGTH / 2, Path.Direction.CW); //保存当前canvas 状态 canvas.save(); @@ -636,18 +721,18 @@ private void drawOvalUsePath(Canvas canvas) { */ private int isInTheCornerCircle(float x, float y) { Integer[] except = null; - if (TOUCH_CORNER_LINE_SCALE && TOUCH_MIDDLE_LINE_SCALE){//全部触发缩放 + if (TOUCH_CORNER_LINE_SCALE && TOUCH_MIDDLE_LINE_SCALE) {//全部触发缩放 except = null; - }else if (TOUCH_CORNER_LINE_SCALE){//拐角触发缩放 - except = new Integer[]{4,5,6,7}; - }else if(TOUCH_MIDDLE_LINE_SCALE){//中间线触发缩放 - except = new Integer[]{0,1,2,3}; - }else { - except = new Integer[]{0,1,2,3,4,5,6,7}; + } else if (TOUCH_CORNER_LINE_SCALE) {//拐角触发缩放 + except = new Integer[]{4, 5, 6, 7}; + } else if (TOUCH_MIDDLE_LINE_SCALE) {//中间线触发缩放 + except = new Integer[]{0, 1, 2, 3}; + } else { + except = new Integer[]{0, 1, 2, 3, 4, 5, 6, 7}; } - return QLHUtils.isInTheCornerCircle(x,y, + return QLHUtils.isInTheCornerCircle(x, y, four_corner_coordinate_positions, - RECT_CORNER_HEIGHT,except); + RECT_CORNER_HEIGHT, except); } /** @@ -809,7 +894,7 @@ private void getoffsetXandoffsetY() { * @param offsetY Y轴偏移量 */ private void changeEightCoordinatePositions(int point, int offsetX, int offsetY) { - QLHUtils.changePositions(point,offsetX,offsetY,four_corner_coordinate_positions,max); + QLHUtils.changePositions(point, offsetX, offsetY, four_corner_coordinate_positions, max); } /** @@ -822,7 +907,7 @@ private void notifyNowBorderLength() { float d = four_corner_coordinate_positions[1][1]; float temp1 = (float) Math.pow(a - c, 2); float temp2 = (float) Math.pow(b - d, 2); - BORDER_LENGTH = (float) Math.sqrt(temp1 + temp2); + BORDER_LENGTH = (int) Math.sqrt(temp1 + temp2); } diff --git a/cropviewlibrary/src/main/res/values/attrs.xml b/cropviewlibrary/src/main/res/values/attrs.xml index 6895bd1..ebe3929 100644 --- a/cropviewlibrary/src/main/res/values/attrs.xml +++ b/cropviewlibrary/src/main/res/values/attrs.xml @@ -24,6 +24,8 @@ + + \ No newline at end of file