Android Matrix處理ImageView中圖片縮放,平移
1,Matrix 原理簡單介紹
Matrix :矩陣,線性代數裡有介紹,結合Matrix,用於平面的縮放、平移、旋轉等操作。
首先介紹一下矩陣運算。加法和減法就不用說了,太簡單了,對應位相加就好。影象處理,主要用到的是乘法 。下面是一個乘法的公式:
在 Android 裡面, Matrix 由 9 個 float 值構成,是一個 3*3 的矩陣。如下圖。
2,Android裡面提供了對Matrix操作的一系列方便的介面。
Matrix的操作,總共分為translate(平移),rotate(旋轉),scale(縮放)和skew(傾斜)四種,每一種變換在
Android的API裡都提供了set, post和pre三種操作方式,
set是直接設定Matrix的值,每次set一次,整個Matrix的陣列都會變掉。
post是後乘,當前的矩陣乘以引數給出的矩陣。可以連續多次使用post,來完成所需的整個變換。例如,要將一個圖片旋
轉30度,然後平移到(100,100)的地方,那麼可以這樣做:
Matrix m = new Matrix();
m.postRotate(30);
m.postTranslate(100, 100);
下面給出一個例子。
- package chroya.demo.graphics;
-
import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.Canvas;
- import android.graphics.Matrix;
- import android.graphics.Rect;
- import android.graphics.drawable.BitmapDrawable;
- import android.util.DisplayMetrics;
- import android.view.MotionEvent;
-
import android.view.View;
- publicclass MyView extends View {
- private Bitmap mBitmap;
- private Matrix mMatrix = new Matrix();
- public MyView(Context context) {
- super(context);
- initialize();
- }
- privatevoid initialize() {
- Bitmap bmp = ((BitmapDrawable)getResources().getDrawable(R.drawable.show)).getBitmap();
- mBitmap = bmp;
- /*首先,將縮放為100*100。這裡scale的引數是比例。有一點要注意,如果直接用100/
- bmp.getWidth()的話,會得到0,因為是整型相除,所以必須其中有一個是float型的,直接用100f就好。*/
- mMatrix.setScale(100f/bmp.getWidth(), 100f/bmp.getHeight());
- //平移到(100,100)處
- mMatrix.postTranslate(100, 100);
- //傾斜x和y軸,以(100,100)為中心。
- mMatrix.postSkew(0.2f, 0.2f, 100, 100);
- }
- @Overrideprotectedvoid onDraw(Canvas canvas) {
- // super.onDraw(canvas); //如果介面上還有其他元素需要繪製,只需要將這句話寫上就行了。
- canvas.drawBitmap(mBitmap, mMatrix, null);
- }
- }
執行效果如下:
紅色的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