android圖片裁剪拼接實現(一):Matrix基本使用

NO IMAGE

一、前文

  之前有個朋友委託我實現一個圖片拼接的組件,感覺挺有意思,於是週末花了些時間去研究了下,其實拼接這一步並不難,但是我在研究中發現了Matrix這個東西,非常好的東西。為此,我竟然拾起了多年沒有動過的線性代數。

二、原理

  要徹底搞懂matrix還是需要一定的線性代數上面的理解,不過對於基本使用,瞭解到矩陣乘法就足夠了。
  在android座標系中,分為x、y和z三個軸,分別代表了長、寬、高三個維度。如下圖所示

android圖片裁剪拼接實現(一):Matrix基本使用

  在android中,使用三維座標(x,y,z)組成一個行列式與一個三階行列式進行矩陣乘法。

android圖片裁剪拼接實現(一):Matrix基本使用

  圖中顯示的使用初始座標組成的矩陣與單位矩陣進行矩陣乘法。矩陣乘法使用可以參考矩陣乘法
  Martix會把輸入進來的矩陣帶入到其內部的矩陣中進行計算,最終輸出新的矩陣,來達到對圖形形態的處理。

三、基本方法的使用

  Matrix提供的基本方法有三種模式,

  1. setXXX()方法,例如 setRotate(),setScale()
  2. preXXX()方法,例如 preRotate(),preScale()
  3. postXXX()方法,例如 postRotate(),postScale()

    其中,setXXX()會先將矩陣重置為單位矩陣,然後再進行矩陣變幻
    preXXX()和postXXX()方法會牽扯到矩陣的前乘和後乘,如果瞭解了矩陣乘法規則,就會明白矩陣前乘和後乘得出來的結果是不一樣的,不過一般情況下都會選擇使用post方法,後乘。
    其中還有擴展方法比如:
  4. mapRect(rect) / mapRect(desRect,orgRect)
      第一個方法即使用原始矩陣代入運算,會將返回的矩陣直接覆蓋在傳入的矩陣中
      第二個方法則是對於需要保存原始矩陣的情況下,會把原始矩陣的計算結果賦值到指定的矩陣中
  5. setRectToRect(src,des,stf)
      這個方法相當於將原始矩陣填充到目標矩陣中,所以也就要求兩個矩陣都是有值的。其中填充模式由第三個參數決定。

        /**
         * 獨立縮放X和Y,直到和src的rect和目標rect確切的匹配。這可能會改變原始rect的寬高比
         */
        FILL(0),
        /**
         * 在保持原有寬高比的情況下計算出一個合適的縮放比例,但也會確保原始rect合適的填入目標rect,
         * 最終會把開始的一個邊與目標的開始邊左邊對齊
         */
        START(1),
        /**
         * 與START類似,不過最終結果會儘可能居中
         */
        CENTER(2),
        /**
         * 與START類似,不過最終結果會儘可能靠右邊
         */
        END(3);
    
  6. invert(inverse)
      反轉矩陣,可以應用到類似倒影一類的實現中
  7. setPolyToPoly(src,srcIndex,dst,dstIndex,pointCount)
      這是一個比較神奇的方法。隨著pointCount點數量,可以對原始矩陣進行平移、旋轉、錯切、翻頁效果。功能非常強大。

    此外,關於Matrix還有顏色變幻等效果,更多擴展用法後面會講到。

四、實踐到自定義view中

  寫一個自定義view,最重要的是要了解view的繪製過程。簡單的繪製流程如下

android圖片裁剪拼接實現(一):Matrix基本使用

其中不帶on的方法都為調度方法,不可被重寫,這些方法裡面會把前期一些必要的數據準備出來,帶on前綴的方法都是實際進行處理的方法。
measure方法是測量控件大小的,layout是用來佈局,根據measure測量的結果,把其中每個元素在其內部進行位置的計算。最後會執行的draw方法,draw也分為draw和onDraw,可以根據自己需求來改寫對應的方法。
其中,onMeasure的方法如下所示:

所有影響尺寸計算相關的方法都會放到這個measure裡面進行計算,比如scale和rotate,都會影響size大小。所以在這裡計算完成後,好在layout中進行正確的佈局。
layout中的代碼如下:

兩個方法中,要做到Matrix多效果疊加,切記要保留一個bitmap最原始的矩陣,然後再接下來的計算中需要用到當前尺寸的時候,使用Martix計算出臨時的尺寸對其進行計算。
兩個方法中,Bitmap被封裝到一個ImageData類裡面,進行對象化,這樣可以更好的管理Bitmap的處理和數據記錄。
ImageData如下:

這裡面跟本文無關的方法都隱藏了,隨後會講到.
那麼我們來看看效果

android圖片裁剪拼接實現(一):Matrix基本使用

使用方法,跟目錄gradle裡面添加:

app.gradle中添加:

本文代碼:github.com/Kongdy/Imag…
個人github地址:github.com/Kongdy
個人掘金主頁:juejin.im/user/595a64…
csdn主頁:blog.csdn.net/u014303003

相關文章

Python讓你的Web應用程飛起來全家桶之Sanic

讓你的Python(Web應用)飛起來,(異步/協程)全家桶

vuevuexvuerouter後臺項目——權限路由(超詳細簡單版)

基本數據結構梳理