Matrix包含一個(gè)3 X 3的矩陣,專門用于圖像變換匹配。
創(chuàng)新互聯(lián)專注于林甸企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),購(gòu)物商城網(wǎng)站建設(shè)。林甸網(wǎng)站建設(shè)公司,為林甸等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站設(shè)計(jì),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)
Matrix提供了四種操作:
translate(平移)
rotate(旋轉(zhuǎn))
scale(縮放)
skew(傾斜)
也就是說這4種操作都是對(duì)這個(gè)3 X 3的矩陣設(shè)值來(lái)達(dá)到變換的效果。
Matrix沒有結(jié)構(gòu)體,它必須被初始化,通過reset或set方法。
OK,Matrix介紹完了,我們來(lái)看看set、pre、post的區(qū)別。
pre是在隊(duì)列最前面插入,post是在隊(duì)列最后面追加,而set先清空隊(duì)列在添加(這也是上文提到的“Matrix沒有結(jié)構(gòu)體,它必須被初始化,通過reset或set方法”的原因)。
下面通過一些例子具體說明:
matrix.preScale(2f,1f);
matrix.preTranslate(5f, 0f);
matrix.postScale(0.2f, 1f);
matrix.postTranslate(0.5f, 0f);
執(zhí)行順序:translate(5, 0) - scale(2f, 1f) - scale(0.2f, 1f) - translate(0.5f, 0f)
matrix.postTranslate(2f, 0f);
matrix.preScale(0.2f, 1f);
matrix.setScale(1f, 1f);
matrix.postScale(5f, 1f);
matrix.preTranslate(0.5f, 0f);
執(zhí)行順序:translate(0.5f, 0f) - scale(1f, 1f) - scale(5f, 1)
Android本身的android.graphics.Bitmap實(shí)現(xiàn)
一般在Android使用圖片,都會(huì)用到這個(gè)類,這個(gè)類中有一個(gè)函數(shù):
getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height)
Returns in pixels[] a copy of the data in the bitmap.
功能和你要求的類似,只不過返回的是一位數(shù)組,轉(zhuǎn)成二維數(shù)組應(yīng)該不是問題吧。
使用是需注意,對(duì)于比較大的圖片,你的操作很可能會(huì)比較占用內(nèi)存,需要處理一下out of memory的exception。
[img]先上效果圖
源碼
單點(diǎn)拖動(dòng)圖片對(duì)圖片進(jìn)行平移操作。雙手縮放圖片大小和旋轉(zhuǎn)圖片到一定的角度。圖片縮放的時(shí)候 不能大于最大的縮放因子和小于最小的縮放因子。大于最大縮放因子或者小于最小縮放因子需要對(duì)圖像進(jìn)行回彈。圖片旋轉(zhuǎn)的角度只能為90度的倍數(shù),不滿足90度要進(jìn)行回彈。圖片回彈要一個(gè)漸變的效果。
大體思路: 首先,Android中提供了Matrix類可以對(duì)圖像進(jìn)行處理。其次,要顯示一張圖片最容易想到的就是ImageView?;貜椧鬂u變的過程,可以通過屬性動(dòng)畫進(jìn)行設(shè)置。所以大體的思路是:繼承ImageView,重寫onTouchEvent()方法,判斷事件類型,在對(duì)應(yīng)的事件使用Matrix對(duì)圖像進(jìn)行變換。
Matrix是一個(gè)已經(jīng)封裝好的矩陣,最重要的作用就是對(duì)坐標(biāo)點(diǎn)進(jìn)行變換。
舉個(gè)栗子:
1.某個(gè)點(diǎn)(x0,y0,1)通過單位矩陣E映射得到的點(diǎn)還是(x0,y0,1)。
3.點(diǎn)(x0,y0,1)通過矩陣T映射得到的點(diǎn)就會(huì)做如下的變換
可以看到點(diǎn)(x0,y0,1)經(jīng)過T矩陣在x軸方向上平移了dx,在y軸方向上平移了dy。
通過以上的變換可以得到具體的思路: 我們維護(hù)一個(gè)圖像對(duì)應(yīng)的矩陣mCurrentMatrix,該矩陣主要是對(duì)ImageView中的圖像的各個(gè)點(diǎn)進(jìn)行映射。ImageView在容器位置擺放完成之后,置mCurrentMatrix矩陣為單位矩陣。當(dāng)onTouchEvent()方法中觸發(fā)單點(diǎn)觸控并且手指進(jìn)行平移的時(shí)候,調(diào)用矩陣mCurrentMatrix的postTranslate(dx,dy),對(duì)mCurrentMatrix進(jìn)行變換。當(dāng)手指抬起,利用變換結(jié)束后的矩陣對(duì)圖像的各個(gè)點(diǎn)進(jìn)行映射,從而得到平移變換后的圖像。同理可得,在兩只手指進(jìn)行縮放旋轉(zhuǎn)的時(shí)候,我們對(duì)矩陣mCurrentMatrix進(jìn)行各種變換,當(dāng)縮放旋轉(zhuǎn)的事件結(jié)束再利用變換完的矩陣去映射圖像的各個(gè)點(diǎn),從而得到縮放、旋轉(zhuǎn)后的圖像。
安卓自定義View進(jìn)階 - Matrix原理
安卓自定義View進(jìn)階 - Matrix詳解
首先理清事件的邏輯:
初始化圖像大小和位置
縮放圖像大小和控件大小自適應(yīng),平移圖像中心和控件中心重合
onTouchEvent()函數(shù)
平移操作
將圖像對(duì)應(yīng)的矩陣進(jìn)行變換。
縮放操作
mBoundRectF為記錄圖像邊界的矩形??s放的時(shí)候選取圖像的中心進(jìn)行縮放。
旋轉(zhuǎn)操作
旋轉(zhuǎn)的時(shí)候旋轉(zhuǎn)的旋轉(zhuǎn)中心也是圖像的中心
圖像中各個(gè)點(diǎn)的映射
調(diào)用ImageView的setImageMatrix(Matrix matrix)會(huì)讓ImageView根據(jù)設(shè)置的matrix去重新繪制圖像。
更新圖像的矩形邊界
獲得圖像的矩形,并根據(jù)矩陣映射矩形各個(gè)點(diǎn)的坐標(biāo)。
縮放回彈
旋轉(zhuǎn)回彈
一些計(jì)算方法
要求圖像的變換是一個(gè)漸變的過程,很容易想到的就是屬性動(dòng)畫。因?yàn)閷傩詣?dòng)畫本身就是對(duì)值進(jìn)行不斷set的過程。而我們維護(hù)的矩陣也是一個(gè)值,所以很自然可以想到,如果得到回彈之前的矩陣的值以及回彈之后矩陣的值,就可以根據(jù)動(dòng)畫監(jiān)聽器中動(dòng)畫當(dāng)前的系數(shù)值去改變矩陣的值。
對(duì)animator對(duì)象設(shè)置完監(jiān)聽器之后,就可以在手指抬起的時(shí)候調(diào)用屬性動(dòng)畫的start()方法開啟動(dòng)畫。
自定義可平移、縮放、旋轉(zhuǎn)的控件主要點(diǎn)有兩個(gè)方面:一是onTouchEvent()中判斷平移、旋轉(zhuǎn)、縮放的觸發(fā)條件,平移位移量、縮放比例因子、旋轉(zhuǎn)角度的計(jì)算。二是Matrix矩陣的應(yīng)用。
1、設(shè)置圖片位置坐標(biāo)
matrix.postTranslate(x,y) ——這個(gè)(x,y)為圖片左上角的位置
2、設(shè)置圖片圖片中心點(diǎn)為中心旋轉(zhuǎn)
matrix.postRotate(角度, x, y);——這個(gè)(x,y)為圖片中心點(diǎn)的位置
3、渲染圖片
canvas.drawBitmap( BIT , matrix , new Paint());
Android 布局文件View控件的隨機(jī)排列需要使用ListView控件或者GridView控件來(lái)實(shí)現(xiàn),原理是利用Adapter隨機(jī)數(shù)據(jù)源來(lái)實(shí)現(xiàn)的。
使用自定義Adapter綁定數(shù)據(jù)。
使用集合隨機(jī)
Collections.shuffle(list); adapter.setData(list);,并設(shè)置將數(shù)據(jù)綁定到適配器中。
重新刷機(jī)列表 adapter.notifyDataSetChanged();
刷新控件列表后,即實(shí)現(xiàn)了隨機(jī)的功能。