Android Matrix处理ImageView中图片缩放,平移

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);   

下面给出一个例子。

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。

抽象的说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重新设置了矩阵的值,之前的两个变换是无效的了,所以最终的显示效果只有三个变换效果。

posted @ 2016-04-05 17:49  水火379  阅读(3135)  评论(0编辑  收藏  举报