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

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Android 照片選擇區(qū)域功能實(shí)現(xiàn)示例

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

實(shí)現(xiàn) Android 的照片選擇區(qū)域功能

Android 照片選擇區(qū)域功能實(shí)現(xiàn)示例

主要有參考 pqpo/SmartCropper

1, 顯示

顯示四條邊和八個(gè)點(diǎn),

八個(gè)點(diǎn): 4 個(gè)角和 4 條邊的中點(diǎn)

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

繪制

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

具體繪制部分:

繪制八個(gè)點(diǎn)

protected void onDrawPoints(Canvas canvas) {if (!checkPoints(mCropPoints)) { return;}// 繪制 4 個(gè)角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(); // 中間錨點(diǎn) // 繪制 4 條邊上的中點(diǎn) 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 條邊上的中點(diǎn)前,

先算出當(dāng)前 4 條邊上中點(diǎn)的位置

public void setEdgeMidPoints(){// 中點(diǎn)不存在,就新建if (mEdgeMidPoints == null){ mEdgeMidPoints = new Point[4]; for (int i = 0; i < mEdgeMidPoints.length; i++){mEdgeMidPoints[i] = new Point(); }}// 維護(hù) 4 個(gè)頂點(diǎn)的位置,// 通過(guò)頂點(diǎn)的位置,算出邊上中點(diǎn)的位置int len = mCropPoints.length;for (int i = 0; i < len; i++){ // 為了避免極端情況, // 采用 ( 坐標(biāo) + 距離的一半 ) 的方式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, 拖動(dòng)

拖動(dòng)分 2 種情況,角點(diǎn)拖拽,中點(diǎn)平移

8 個(gè)類(lèi)型, 4 個(gè)角點(diǎn)拖拽,4 個(gè)中點(diǎn)平移

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

移動(dòng)的處理

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

識(shí)別到,當(dāng)前點(diǎn)

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

找出當(dāng)前的點(diǎn),的方法

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 ,角點(diǎn)拖拽

先介紹 4 個(gè)角點(diǎn)拖拽

private void toImagePointSize(Point dragPoint, MotionEvent event) {if (dragPoint == null) { return;}// 找出當(dāng)前移動(dòng)類(lèi)型,// 是角點(diǎn)拖拽,還是中點(diǎn)平移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);// 判斷可以移動(dòng)// ... if (DragPointType.isEdgePoint(pointType)){ // ... // 中點(diǎn)平移} else { // 角點(diǎn)拖拽 // 實(shí)現(xiàn)很簡(jiǎn)單, // 更新就好了 dragPoint.y = y; dragPoint.x = x;} }

找出當(dāng)前移動(dòng)類(lèi)型,

是角點(diǎn)拖拽,還是中點(diǎn)平移

// 拿采集的點(diǎn),找出對(duì)應(yīng)的類(lèi)型private DragPointType getPointType(Point dragPoint){if (dragPoint == null) return null;DragPointType type;// 看,是不是頂點(diǎn) / 角點(diǎn)if (checkPoints(mCropPoints)) { for (int i = 0; i < mCropPoints.length; i++) {if (dragPoint == mCropPoints[i]) { // 找到了,直接返回 type = DragPointType.values()[i]; return type;} }}// 看,是不是中點(diǎn)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,中點(diǎn)平移

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

拿到偏移向量,修改對(duì)應(yīng)的兩個(gè)頂點(diǎn)的坐標(biāo)

private void moveEdge(DragPointType type, int xoff, int yoff){switch (type){ case TOP:// 這邊的平移,比較簡(jiǎn)單// 找到中點(diǎn),旁邊的兩個(gè)焦點(diǎn)// 再移動(dòng)位置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;} }

簡(jiǎn)單的平移代碼

拿到偏移向量, 修改坐標(biāo),完事

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; }

中點(diǎn)平移增強(qiáng)

這里的中點(diǎn)平移,拿到平移向量后,

直接添加到中點(diǎn)旁邊的兩個(gè)角點(diǎn)上

效果增強(qiáng)為,中點(diǎn)平移,中點(diǎn)旁邊的兩個(gè)角點(diǎn)順著兩側(cè)邊,做平移計(jì)算稍微復(fù)雜,

知道中點(diǎn)之前的位置,和中點(diǎn)之后的位置,

知道中點(diǎn)與一角點(diǎn),所在邊的斜率,

知道此角點(diǎn)的另一邊的斜率

知道角點(diǎn),平移前的位置,

求解出角點(diǎn),平移后的位置

這是一個(gè)方程式求解網(wǎng)站

變換坐標(biāo)系,可能簡(jiǎn)單些相關(guān) github

demo 的 gradle 配置

到此這篇關(guān)于Android 照片選擇區(qū)域功能實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Android 照片選擇區(qū)域內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Android
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
成人在线免费观看91| av中文字幕在线观看第一页| 久久福利影视| 999精品一区| 99精品综合| 国产精品99在线观看| 在线天堂中文资源最新版| a国产在线视频| 99久久99久久精品国产片果冰| 日韩在线看片| 91久久午夜| 日韩av一区二区三区四区| 日韩精品一区二区三区中文字幕| 亚洲久草在线| 日韩和欧美一区二区三区| 91精品国产经典在线观看| 日韩高清电影一区| 91欧美日韩在线| 久久99免费视频| 国产成人久久精品麻豆二区| 久久婷婷国产| 亚洲午夜电影| 国产精品香蕉| 久久久人人人| 日韩国产在线观看| 成人亚洲一区| 国产精品久久久久蜜臀| 香蕉国产精品| 国产精品蜜月aⅴ在线| 久久中文视频| 国产激情欧美| 免费久久精品视频| 精品99在线| 日韩精品一级| 亚洲欧美一区在线| 日韩二区三区四区| 欧美日韩国产一区二区三区不卡| 精品美女久久| 国产欧美高清视频在线| 中文字幕在线免费观看视频| 四虎国产精品免费观看| 日韩一级精品| 成人亚洲一区| 国产精品白丝一区二区三区| 精品国产乱码久久久| 日韩高清一区在线| 亚洲欧美日韩视频二区| av一区在线| 久久精品国产网站| 日韩免费精品| 91精品国产乱码久久久久久久 | 国产精品成久久久久| 日韩国产欧美视频| 亚洲天堂日韩在线| 国产一区91| 亚洲一区欧美激情| 国产高清一区二区| 久久在线免费| 亚洲夜间福利| 欧美日韩在线观看首页| 久久免费影院| 国产精品美女久久久久久不卡| 亚洲精选久久| 日本午夜免费一区二区| 香蕉久久久久久| 91午夜精品| 麻豆精品久久久| 精品国产乱码久久久久久1区2匹 | 国产视频一区三区| 99在线精品视频在线观看| 在线亚洲精品| 亚洲精品乱码| 欧美三级第一页| 久久精品国产网站| 久久久久国产精品一区二区| 在线看片福利| 尤物精品在线| 亚洲人成网站在线在线观看| 色婷婷成人网| 久久中文欧美| 日本韩国欧美超级黄在线观看| 1000部精品久久久久久久久| 国产精品日本| 国产精品1区| 国产专区一区| 日本特黄久久久高潮| 国产一区三区在线播放| 亚洲夜间福利| 国产欧美午夜| 怡红院精品视频在线观看极品| 尤物精品在线| 丁香婷婷久久| 亚洲欧洲美洲国产香蕉| 理论片午夜视频在线观看| 亚洲午夜在线| 国产精品亚洲二区| 欧美福利一区| 久久精品国产99| 六月婷婷一区| 国产v日韩v欧美v| 日本欧美韩国一区三区| 不卡在线一区二区| 欧美极品中文字幕| 久久最新视频| 日韩精品久久久久久久电影99爱| 日韩中文字幕不卡| 欧美日韩免费观看视频| 日韩一二三区在线观看| 激情久久婷婷| 欧美在线观看视频一区| 久久婷婷国产| 国产欧美日韩免费观看| 美女久久一区| 午夜久久久久| 91tv亚洲精品香蕉国产一区| 国产欧美欧美| 亚洲毛片在线| 亚洲精选91| 免费成人性网站| 尤物在线精品| 日韩精品久久久久久久电影99爱 | 欧美一区二区三区免费看| 国产亚洲欧洲| 国产伊人精品| 亚洲精品日韩久久| 日本少妇一区| а√天堂8资源中文在线| 国产日韩欧美在线播放不卡| 午夜精品成人av| 日韩不卡一区| 粉嫩av一区二区三区四区五区 | 精品欧美一区二区三区在线观看| 麻豆精品在线| 国产劲爆久久| а√天堂8资源在线| 日韩欧美字幕| 亚洲精品a级片| 免费在线看一区| 日韩精品91亚洲二区在线观看| 蜜桃伊人久久| 色狠狠一区二区三区| 国产日产精品_国产精品毛片| 国产精品伊人| 免费高潮视频95在线观看网站| 欧美黄页在线免费观看 | 欧美午夜三级| 久久久久久婷| 免费日韩av片| 国产精品xvideos88| 国产在线观看91一区二区三区| 少妇久久久久| 亚洲精品一区二区在线播放∴| 国产精品免费99久久久| 久久精品免费一区二区三区| 影音国产精品| 久久不卡国产精品一区二区| 成人片免费看| 蜜桃伊人久久| 麻豆精品视频在线观看免费| 99精品网站| 国产一卡不卡| 国产精品人人爽人人做我的可爱| 免费看黄色91| 欧美日韩精品在线一区| 日韩1区2区3区| 欧美一区二区三区高清视频| 欧美一区成人| 香蕉精品999视频一区二区| 欧美极品中文字幕| 免费精品视频| 亚洲手机在线| 中文字幕成在线观看| 亚洲毛片网站| 一区二区三区视频免费观看| 国产欧美大片| 亚洲免费观看高清完整版在线观| 91一区二区| 久久亚洲人体| 国产欧美日韩免费观看| 快she精品国产999| 日韩和的一区二在线| 欧美黄页在线免费观看| 日韩精品久久久久久| 久久高清国产| 亚洲免费影视| 亚洲精华国产欧美| 伊人久久亚洲热| 国产一区日韩一区| 成人日韩av| 成人在线视频中文字幕| 国产精品美女午夜爽爽| 国产精品一区二区精品| 69堂精品视频在线播放| 日韩高清成人在线| 婷婷视频一区二区三区| 婷婷综合福利| 国产精品三级| 国产一区二区三区日韩精品| 欧美激情国产在线| 国产综合婷婷|