Android畫圖之Matrix(深入)

作者:GangWang 

出處:http://www.cnblogs.com/GnagWang/ 

Matrix ,中文裏叫矩陣,高等數學裏有介紹,在圖像處理方面,主要是用於平面的縮放、平移、旋轉等操作。

首先介紹一下矩陣運算。加法和減法就不用說了,太簡單了,對應位相加就好。圖像處理,主要用到的是乘法 。下面是一個乘法的公式:

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

沒專業工具,畫的挺難看。解釋一下,上面的 sinX 和 cosX ,表示旋轉角度的 cos 值和 sin 值,注意,旋轉角度是按順時針方向計算的。 translateX 和 translateY 表示 x 和 y 的平移量。 scale 是縮放的比例, 1 是不變, 2 是表示縮放 1/2 ,這樣子。

下面在 Android 上試試 Matrix 的效果

public class MyView extends View {

    private Bitmap mBitmap;

    private Matrix mMatrix = new Matrix();

    public MyView(Context context) {

        super(context);

        initialize();

    }

    private void initialize() {       

        mBitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.show)).getBitmap();       

        float cosValue = (float) Math.cos(-Math.PI/6);

        float sinValue = (float) Math.sin(-Math.PI/6);

        mMatrix.setValues(

                new float[]{

                        cosValue, -sinValue, 100,

                        sinValue, cosValue, 100,

                        0, 0, 2});

    }

    @Override protected void onDraw(Canvas canvas) {

//        super.onDraw(canvas);  //當然,如果界面上還有其他元素需要繪製,只需要將這句話寫上就行了。

        canvas.drawBitmap(mBitmap, mMatrix, null);

    }

}

運行結果如下:

以左上角爲頂點,縮放一半,逆時針旋轉30度,然後沿x軸和y軸分別平移50個像素,代碼 裏面寫的是100,爲什麼是平移50呢,因爲縮放了一半。

       大家可以自己設置一下Matrix的值,或者嘗試一下兩個Matrix相乘,得到的值設置進去,這樣才能對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);  

這樣就達到了想要的效果。

pre是前乘,參數給出的矩陣乘以當前的矩陣。所以操作是在當前矩陣的最前面發生的。例如上面的例子,如果用pre的話,就要這樣:

Matrix m = new Matrix();
m.setTranslate(100, 100);
m.preRotate(30);

旋轉、縮放和傾斜都可以圍繞一箇中心點來進行,如果不指定,默認情況下,是圍繞(0,0)點來進行。

下面給出一個例子。

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;

public class MyView extends View { 
    
    private Bitmap mBitmap; 
    private Matrix mMatrix = new Matrix(); 
    
    public MyView(Context context) { 
        super(context); 
        initialize(); 
    }

    private void 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); 
    } 
    
    @Override protected void onDraw(Canvas canvas) { 
//        super.onDraw(canvas);  //如果界面上還有其他元素需要繪製,只需要將這句話寫上就行了。 
        
        canvas.drawBitmap(mBitmap, mMatrix, null); 
    } 
} 

運行效果如下:

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章