1. 程式人生 > >Android Matrix處理ImageView中圖片縮放,平移

Android Matrix處理ImageView中圖片縮放,平移

1,Matrix 原理簡單介紹

      Matrix :矩陣,線性代數裡有介紹,結合Matrix,用於平面的縮放、平移、旋轉等操作。 
首先介紹一下矩陣運算。加法和減法就不用說了,太簡單了,對應位相加就好。影象處理,主要用到的是乘法 。下面是一個乘法的公式:

77c093fd-764d-376e-abf6-08400901c306.png



在 Android 裡面, Matrix 由 9 個 float 值構成,是一個 3*3 的矩陣。如下圖。


80c2af69-8b1f-36c8-a364-f133559d066b.png

2,Android裡面提供了對Matrix操作的一系列方便的介面。

    Matrix的操作,總共分為translate(平移),rotate(旋轉),scale(縮放)和skew(傾斜)四種,每一種變換在

Android的API裡都提供了set, post和pre三種操作方式,

除了translate,其他三種操作都可以指定中心點


    set是直接設定Matrix的值,每次set一次,整個Matrix的陣列都會變掉


    post是後乘,當前的矩陣乘以引數給出的矩陣。可以連續多次使用post,來完成所需的整個變換。例如,要將一個圖片旋
轉30度,然後平移到(100,100)的地方,那麼可以這樣做:

Matrix m = new Matrix();  
m.postRotate(30);  
m.postTranslate(100, 100); 

 下面給出一個例子。

  1. package chroya.demo.graphics;    
  2. import android.content.Context;    
  3. import android.graphics.Bitmap;    
  4. import android.graphics.Canvas;    
  5. import android.graphics.Matrix;    
  6. import android.graphics.Rect;    
  7. import android.graphics.drawable.BitmapDrawable;    
  8. import android.util.DisplayMetrics;    
  9. import android.view.MotionEvent;    
  10. import android.view.View;    
  11. publicclass MyView extends View {    
  12.     private Bitmap mBitmap;    
  13.     private Matrix mMatrix = new Matrix();    
  14.     public MyView(Context context) {    
  15.         super(context);    
  16.         initialize();    
  17.     }    
  18.     privatevoid initialize() {    
  19.         Bitmap bmp = ((BitmapDrawable)getResources().getDrawable(R.drawable.show)).getBitmap();    
  20.         mBitmap = bmp;    
  21.         /*首先,將縮放為100*100。這裡scale的引數是比例。有一點要注意,如果直接用100/  
  22. bmp.getWidth()的話,會得到0,因為是整型相除,所以必須其中有一個是float型的,直接用100f就好。*/
  23.         mMatrix.setScale(100f/bmp.getWidth(), 100f/bmp.getHeight());    
  24.                 //平移到(100,100)處  
  25.         mMatrix.postTranslate(100100);    
  26.                 //傾斜x和y軸,以(100,100)為中心。  
  27.         mMatrix.postSkew(0.2f, 0.2f, 100100);    
  28.     }    
  29.     @Overrideprotectedvoid onDraw(Canvas canvas) {    
  30. //      super.onDraw(canvas);  //如果介面上還有其他元素需要繪製,只需要將這句話寫上就行了。  
  31.         canvas.drawBitmap(mBitmap, mMatrix, null);    
  32.     }    
  33. }    


 執行效果如下:

   紅色的x和y表示傾斜的角度,下面是x,上面是y。


抽象的說pre方法是向前"生長", post方法是向後"生長",具體拿個例子來說,比如一個matrix呼叫了下列一系列的方法:

   matrix.preScale(0.5f, 1);  matrix.preTranslate(10, 0); matrix.postScale(0.7f, 1);  matrix.postTranslate(15, 0); 則座標變換經過的4個變換過程依次是:

translate(10, 0) -> scale(0.5f, 1) -> scale(0.7f, 1) -> translate(15, 0),

所以對matrix方法的呼叫順序是很重要的,不同的順序往往會產生不同的變換效果。pre方法的呼叫順序和post方法的互不影響,即以下的方法呼叫和前者在真實座標變換順序裡是一致的, 

matrix.postScale(0.7f, 1); matrix.preScale(0.5f, 1);  matrix.preTranslate(10, 0); matrix.postTranslate(15, 0);

  而matrix的set方法則會對先前的pre和post操作進行刷除,而後再設定它的值,比如下列的方法呼叫: 

matrix.preScale(0.5f, 1);  matrix.postTranslate(10, 0); matrix.setScale(1, 0.6f); matrix.postScale(0.7f, 1);

 matrix.preTranslate(15, 0); 其座標變換順序是

translate(15, 0) -> scale(1, 0.6f) ->  scale(0.7f, 1).

setScale重新設定了矩陣的值,之前的兩個變換是無效的了,所以最終的顯示效果只有三個變換效果。


        demo:http://download.csdn.net/detail/guitk/8037203