日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Android 照片選擇區域功能實現示例

瀏覽:30日期:2022-09-19 09:10:10

實現 Android 的照片選擇區域功能

Android 照片選擇區域功能實現示例

主要有參考 pqpo/SmartCropper

1, 顯示

顯示四條邊和八個點,

八個點: 4 個角和 4 條邊的中點

/* 裁剪區域,0, 左上 -> LeftTop, 1, 右上 -> RightTop,2, 右下 -> RightBottom, 3, 左下 -> LeftBottom*/Point[] mCropPoints;// 4 條邊的中點Point[] mEdgeMidPoints;

繪制

protected void onDrawCropPoint(Canvas canvas) {//繪制蒙版onDrawMask(canvas);//繪制輔助線onDrawGuideLine(canvas);//繪制選區線onDrawLines(canvas);//繪制錨點onDrawPoints(canvas);//繪制放大鏡// ... }

具體繪制部分:

繪制八個點

protected void onDrawPoints(Canvas canvas) {if (!checkPoints(mCropPoints)) { return;}// 繪制 4 個角for (Point point : mCropPoints) { canvas.drawCircle(getViewPointX(point), getViewPointY(point), dp2px(POINT_RADIUS), mPointFillPaint); canvas.drawCircle(getViewPointX(point), getViewPointY(point), dp2px(POINT_RADIUS), mPointPaint);}if (mShowEdgeMidPoint) { setEdgeMidPoints(); // 中間錨點 // 繪制 4 條邊上的中點 for (Point point : mEdgeMidPoints){canvas.drawCircle(getViewPointX(point), getViewPointY(point), dp2px(POINT_RADIUS), mPointFillPaint);canvas.drawCircle(getViewPointX(point), getViewPointY(point), dp2px(POINT_RADIUS), mPointPaint); }} }

繪制 4 條邊上的中點前,

先算出當前 4 條邊上中點的位置

public void setEdgeMidPoints(){// 中點不存在,就新建if (mEdgeMidPoints == null){ mEdgeMidPoints = new Point[4]; for (int i = 0; i < mEdgeMidPoints.length; i++){mEdgeMidPoints[i] = new Point(); }}// 維護 4 個頂點的位置,// 通過頂點的位置,算出邊上中點的位置int len = mCropPoints.length;for (int i = 0; i < len; i++){ // 為了避免極端情況, // 采用 ( 坐標 + 距離的一半 ) 的方式mEdgeMidPoints[i].set(mCropPoints[i].x + (mCropPoints[(i+1)%len].x - mCropPoints[i].x)/2, mCropPoints[i].y + (mCropPoints[(i+1)%len].y - mCropPoints[i].y)/2);} }2, 拖動

拖動分 2 種情況,角點拖拽,中點平移

8 個類型, 4 個角點拖拽,4 個中點平移

enum DragPointType{LEFT_TOP,RIGHT_TOP,RIGHT_BOTTOM,LEFT_BOTTOM,TOP,RIGHT,BOTTOM,LEFT;// 判斷是角點拖拽,不是中點平移public static boolean isEdgePoint(DragPointType type){ return type == TOP || type == RIGHT || type == BOTTOM || type == LEFT;} }

移動的處理

@Override public boolean onTouchEvent(MotionEvent event) {int action = event.getAction();boolean handle = true;switch (action) { case MotionEvent.ACTION_DOWN:// 識別到,當前點mDraggingPoint = getNearbyPoint(event);if (mDraggingPoint == null) { handle = false;}break; case MotionEvent.ACTION_MOVE:// 移動toImagePointSize(mDraggingPoint, event);break; case MotionEvent.ACTION_UP:// 手指抬起,// 操作取消mDraggingPoint = null;break;}// 繪制// 更新完位置后,刷新繪制invalidate();return handle || super.onTouchEvent(event); }

識別到,當前點

private Point getNearbyPoint(MotionEvent event) {// 判斷 4 個角點,可用if (checkPoints(mCropPoints)) { for (Point p : mCropPoints) {// 找出當前的點if (isTouchPoint(p, event)) return p; }}// 判斷 4 個中點可用if (checkPoints(mEdgeMidPoints)) { for (Point p : mEdgeMidPoints){// 找出當前的點if (isTouchPoint(p, event)) return p; }}return null; }

找出當前的點,的方法

private static final float TOUCH_POINT_CATCH_DISTANCE = 15;private boolean isTouchPoint(Point p, MotionEvent event){float x = event.getX();float y = event.getY();float px = getViewPointX(p);float py = getViewPointY(p);double distance = Math.sqrt(Math.pow(x - px, 2) + Math.pow(y - py, 2));// 也就是,判斷距離if (distance < dp2px(TOUCH_POINT_CATCH_DISTANCE)) { return true;}return false; }2.1 ,角點拖拽

先介紹 4 個角點拖拽

private void toImagePointSize(Point dragPoint, MotionEvent event) {if (dragPoint == null) { return;}// 找出當前移動類型,// 是角點拖拽,還是中點平移DragPointType pointType = getPointType(dragPoint);int x = (int) ((Math.min(Math.max(event.getX(), mActLeft), mActLeft + mActWidth) - mActLeft) / mScaleX);int y = (int) ((Math.min(Math.max(event.getY(), mActTop), mActTop + mActHeight) - mActTop) / mScaleY);// 判斷可以移動// ... if (DragPointType.isEdgePoint(pointType)){ // ... // 中點平移} else { // 角點拖拽 // 實現很簡單, // 更新就好了 dragPoint.y = y; dragPoint.x = x;} }

找出當前移動類型,

是角點拖拽,還是中點平移

// 拿采集的點,找出對應的類型private DragPointType getPointType(Point dragPoint){if (dragPoint == null) return null;DragPointType type;// 看,是不是頂點 / 角點if (checkPoints(mCropPoints)) { for (int i = 0; i < mCropPoints.length; i++) {if (dragPoint == mCropPoints[i]) { // 找到了,直接返回 type = DragPointType.values()[i]; return type;} }}// 看,是不是中點if (checkPoints(mEdgeMidPoints)) { for (int i = 0; i < mEdgeMidPoints.length; i++){if (dragPoint == mEdgeMidPoints[i]){ // 找到了,直接返回 type = DragPointType.values()[4+i]; return type;} }}return null; }2.2,中點平移

private void toImagePointSize(Point dragPoint, MotionEvent event) {if (dragPoint == null) { return;}DragPointType pointType = getPointType(dragPoint);int x = // ...int y = // ...// 判斷可以移動// ... if (DragPointType.isEdgePoint(pointType)){ // 中點平移, // 拿到的是,一個偏移向量 int xoff = x - dragPoint.x; int yoff = y - dragPoint.y; moveEdge(pointType, xoff, yoff);} else { // 角點拖拽 // ...} }

拿到偏移向量,修改對應的兩個頂點的坐標

private void moveEdge(DragPointType type, int xoff, int yoff){switch (type){ case TOP:// 這邊的平移,比較簡單// 找到中點,旁邊的兩個焦點// 再移動位置movePoint(mCropPoints[P_LT], 0, yoff);movePoint(mCropPoints[P_RT], 0, yoff);break; case RIGHT:// 右移處理movePoint(mCropPoints[P_RT], xoff, 0);movePoint(mCropPoints[P_RB], xoff, 0);break; case BOTTOM:// 下移處理// ... case LEFT:// 左移處理// ... default: break;} }

簡單的平移代碼

拿到偏移向量, 修改坐標,完事

private void movePoint(Point point, int xoff, int yoff){if (point == null) return;int x = point.x + xoff;int y = point.y + yoff;// 檢查邊界if (x < 0 || x > getDrawable().getIntrinsicWidth()) return;if (y < 0 || y > getDrawable().getIntrinsicHeight()) return;point.x = x;point.y = y; }

中點平移增強

這里的中點平移,拿到平移向量后,

直接添加到中點旁邊的兩個角點上

效果增強為,中點平移,中點旁邊的兩個角點順著兩側邊,做平移計算稍微復雜,

知道中點之前的位置,和中點之后的位置,

知道中點與一角點,所在邊的斜率,

知道此角點的另一邊的斜率

知道角點,平移前的位置,

求解出角點,平移后的位置

這是一個方程式求解網站

變換坐標系,可能簡單些相關 github

demo 的 gradle 配置

到此這篇關于Android 照片選擇區域功能實現示例的文章就介紹到這了,更多相關Android 照片選擇區域內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Android
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
99成人超碰| 亚洲视频二区| 国产一卡不卡| 亚洲精品护士| 日韩精品视频一区二区三区| 日本国产一区| 国产精品尤物| 欧美激情日韩| 国产一区二区三区网| 91嫩草亚洲精品| 日本在线高清| 成人精品视频| 婷婷激情一区| 国产高清一区二区| 欧美一级专区| 亚洲v天堂v手机在线| 日韩高清电影一区| 国产精品片aa在线观看| 鲁大师精品99久久久| 精品国产一区二区三区av片| 国产精品国产三级国产在线观看| 国产suv精品一区二区四区视频 | 精品国产99| 日韩a一区二区| 久久精品播放| 蜜臀久久99精品久久久画质超高清| 欧美日韩国产免费观看| 日韩影院精彩在线| 日韩va欧美va亚洲va久久| 国产精品xvideos88| 成人免费一区| 91成人精品视频| 亚洲精品人人| 精品视频在线观看网站| 久久天堂av| 蜜桃91丨九色丨蝌蚪91桃色 | 亚洲一区导航| 欧美午夜三级| 不卡专区在线| 亚洲在线一区| 久久国产成人| 国产福利一区二区精品秒拍| 久久青青视频| 亚洲欧美日韩国产一区| 国产精品亚洲二区| 久久久影院免费| 日韩国产欧美在线播放| 国产一区调教| 亚洲欧美日韩国产一区| 国产精品白丝av嫩草影院| 啪啪国产精品| 亚洲在线久久| 91视频一区| 综合亚洲视频| 精品国产免费人成网站| 综合一区二区三区| 日韩在线免费| 日本一区二区三区视频在线看| 色综合五月天| 无码日韩精品一区二区免费| 成人在线黄色| 亚洲毛片一区| 91精品一区二区三区综合| 97久久中文字幕| 免费久久久久久久久| 欧美日韩夜夜| 午夜国产精品视频| 国产专区精品| 日本色综合中文字幕| 91精品国产自产在线观看永久∴ | 精品一区亚洲| 国产精品xvideos88| 男女精品网站| 亚洲不卡系列| 久久影院资源站| 一级成人国产| 蜜臀91精品国产高清在线观看| 久久国产精品免费一区二区三区| 国产韩日影视精品| 丰满少妇一区| 欧美天堂在线| 日韩制服丝袜av| 欧美日韩国产免费观看视频| 精品国产亚洲一区二区三区| 亚洲人成网77777色在线播放| 欧洲亚洲一区二区三区| 美女久久久久久 | 男女男精品视频网| 丝袜诱惑一区二区| 国产精品欧美在线观看| 亚洲深深色噜噜狠狠爱网站 | 国产精品嫩模av在线| 美日韩精品视频| 久久中文字幕二区| 成人黄色av| 国产精品对白久久久久粗| 一区二区三区网站| 一本一本久久| 99精品国产一区二区三区| 三上亚洲一区二区| 久久亚洲人体| 国产精品久久久久久久免费软件| 日韩中文字幕一区二区高清99| 尤物在线精品| 国产精品88久久久久久| 欧美午夜精彩| 九色porny丨国产首页在线| 国产一区二区三区日韩精品 | 国产精品综合色区在线观看| 中文字幕av亚洲精品一部二部 | 亚洲欧美久久| 午夜久久免费观看| 日韩一区欧美| 国产高清不卡| 亚洲国产欧美日本视频| 日韩理论视频| 精品亚洲美女网站| 久久精品中文| 婷婷成人在线| 亚洲午夜久久久久久尤物 | 国产一区二区三区不卡av| 国产剧情一区| 国产精品一页| 国产极品一区| 美女精品一区二区| 精品国产午夜肉伦伦影院| 麻豆精品视频在线观看免费| 美女在线视频一区| 成人午夜网址| 日本在线高清| 久久中文视频| 中文国产一区| 综合日韩在线| 日韩精品高清不卡| 欧美日韩一区二区高清| 国产精品一区二区免费福利视频| 国产一卡不卡| 精品一区二区三区亚洲| caoporn视频在线| 日本久久成人网| 激情综合网址| 老鸭窝亚洲一区二区三区| 日韩精品一卡二卡三卡四卡无卡| 蜜桃av一区二区三区电影| 青青草伊人久久| 麻豆视频久久| 精品国模一区二区三区| 男女精品网站| 热久久久久久| 国产精品入口久久| 最新中文字幕在线播放| 99精品电影| 蜜臀精品一区二区三区在线观看 | 日韩视频1区| 欧美精品第一区| 福利在线一区| 欧美1区2区3区| 少妇精品久久久一区二区| 国产精品欧美三级在线观看| 综合日韩av| 日韩中文字幕区一区有砖一区| 国产日韩一区二区三免费高清| 久久久久黄色| 亚洲激情中文| 欧美精品三级在线| 中文字幕人成乱码在线观看| 欧美专区一区二区三区| 国产精品欧美大片| 欧美成人基地| 免费视频最近日韩| 精品淫伦v久久水蜜桃| 亚洲午夜精品久久久久久app| 亚洲18在线| 日韩精品2区| 亚洲乱码视频| 日韩久久视频| 亚洲精品少妇| 中文在线а√在线8| 水野朝阳av一区二区三区| 麻豆91精品视频| 亚洲作爱视频| 精品三区视频| 亚洲欧美在线综合| 日韩中文在线电影| 日韩亚洲精品在线观看| se01亚洲视频| 久久激情综合网| 九九久久婷婷| 国产精品v一区二区三区| 欧美1级日本1级| 欧美国产中文高清| 亚洲一区二区三区四区五区午夜 | 国产高清视频一区二区| 高清av一区| 综合一区av| 欧美亚洲精品在线| 另类综合日韩欧美亚洲| 在线精品福利| 日韩欧美看国产| 国产精品嫩草影院在线看|