自定義圖片裁剪之雙指縮放思路

阿壯發表於2019-02-28
  1. 前一段時間產品經理就著圖片裁剪的功能找到我:小哥,這個圖片裁剪怎麼在華為手機上是一個圓形,而小米手機上是一個正方形啊;我說:是啊,我們用的是系統自帶的圖片裁剪功能,不同廠商對Google的裁剪框做了定製化,即使同一廠商的不同型號手機也有可能不一致,而使用系統的裁剪效果可以完美適配所有手機,不存在相容性問題;產品經理說這樣不行,噼裡啪啦列了一堆不統一的壞處,結果就是我要自定義圖片裁剪功能。

  2. 自定義裁剪就自定義裁剪,不就是一個圖片加一個可移動的框嗎,看我的。花了大概10分鐘的時間從github上找一個非常厲害的圖片裁剪庫cropper,這個庫大效果是這樣的:按住裁剪中心,可隨意拖動到圖片的任何位置;按住裁剪框四個角,可放到縮小剪裁框; 還可以設定裁剪框初始大小以及等比縮放。嗯,就它了,於是我把這個庫引入到專案中,看著圖片裁剪的效果心裡美滋滋。

  3. 又過了一段時間,產品經理找我:小哥,你這個圖片裁剪功能有點不對勁啊,怎麼只能拖動不能縮放呢?我說可以啊,你拖動四個角不就可以縮放嗎。但我要的是兩個指頭進行縮放;哦,這樣啊,我先看看,看了一下微信的圖片裁剪和一些手機系統的裁剪功能大致可分為3類:第一類手機不支援雙指縮放,第二類手機雙指縮放背景圖片(主流),第三類手機雙指縮放裁剪框;經過和產品經理一番討論,決定做成雙指縮放裁剪框。

  4. 終於進入今天的主題了,其實自定義圖片裁剪功能不能,處理好圖片顯示和觸控事件,剩下的沒啥了,cropper這個庫在這個基礎上做了大量的封裝;一些設計模式的運用和程式碼的封裝很值得我們學習,具體的我就不分析了,網上有大神對這一塊分析得很詳細,我就補充一下cropper庫沒有的雙指縮放功能。

  5. 雙指縮放主要涉及到oTouchEvent事件,平常我們處理觸控事件,都是處理ACTION_DOWN、ACTION_MOVE、ACTION_UP這三個事件,如果多手指就得處理新增ACTION_POINTER_DOWN和ACTION_POINTER_UP事件,每次執行ACTION_POINTER_DOWN事件時就相當於有新的手指觸控螢幕,執行ACTION_POINTER_UP事件時就等於有額外的手指離開螢幕,通過這兩個事件我們可以準確得出ACTION_MOVE事件執行時有幾個手指在螢幕上,接下來當有多個手指在螢幕上時,我們可通過getX(0)、getX(1)、getX(2)…來獲取每個手指在螢幕上的座標,由於我們只處理雙指縮放,所以這裡只取第一個和第二個手指的座標,根據每次執行的ACTION_MOVE事件時,兩個座標之間距離的變化,來判斷使用者是想放大還是縮小。

  6. 我第一次使用的是兩個座標之間的距離變化來放大縮小裁剪框,由於寬和高都是縮放距離差的一半,所以每次都是等比縮放,這樣有些不符使用者習慣,比如使用者兩個手指分別沿Y軸縮放,裁剪框還是會縮放等比縮放寬和高,後面做了一些改進;改成X座標的差值和Y座標的差值分別縮放裁剪框的寬和高,這樣使用起來比較順手。

  7. 無論雙指是縮放裁剪框還是縮放背景圖,都可以使用上述的思路來處理,當然這只是思路,具體實現還得根據效果來微調,例如縮放框時,根據雙指縮放的距離來縮放框,導致裁剪框縮放速度太慢,我們會給縮放值乘以縮放因子,適當調節達到符合使用者使用的效果;縮放背景圖時,如果縮小圖片,會導致裁剪框超出圖片大小,這裡也要做適當的調整。這裡由於demo是在公司實現的,寫部落格時就沒有貼出程式碼實現,相信讀過一遍這個實現思路,慢慢自己寫出具體效果應該不難。

相關文章