android 图形特效处理 Matrix控制变换

使用Matrix控制变换

Matrix是And戎狄提供的一个矩阵工具类,它本身并不能对图像或者组件进行变换,但可以其他API结合来控制图形,组件的变换

使用Matrix控制图像或者组件变换的步骤如下.

1.获取Matrix对象,该Matrix对象即可新创建,也可直接获取其他对象内封装的Matrix(例如Transfoumation对象内部就封装了Matrix).

2.调用Matrix的方法进行平移,旋转,缩放,倾斜等.

3.将程序对Matrix所做的变换应用到指定图像或组件

Matrix提供了如下方法来控制平移,旋转和缩放:

> setTranslate(float dx, float dy): 控制Matrix进行平移.

> setSkew(float kx, float ky, float px, float py): 控制Matrix以px,py为轴心进行倾斜.kx,ky为X,Y方向上的倾斜距离.

> setSkew(float kx, float ky): 控制Matrix进行倾斜.kx,ky为X,Y方向上的倾斜距离.

> setRotate(float degrees): 控制Matrix进行旋转,degrees控制旋转的角度.

> setRotate(float degrees, float px, float py): 设置以px,py为轴心进行旋转,degrees控制旋转的角度.

> setScale(float sx, float sy): 设置Matrix进行缩放,sx,xy控制X,Y方向上的缩放比例.

> setScale(float sx, float sy, float px, float py): 设置Matrix以px,py为轴心进行缩放,sx,sy控制X,Y方向上的缩放比例.

一旦对Matrix进行了变换,接下来就可应用该Matrix对图形进行控制了.例如Canvas.drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)方法,调用该方法就可以绘制bitmap时应用Matrix上的变换.

如下程序开发了一个自定义View,该自定义View会用matrix对绘制的图形进行旋转,倾斜变换.


1.自定义View

package com.example.matrixdemo.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.View;
import com.example.matrixdemo.R;

/**
 * 图形的旋转,倾斜变换
 * 
 * @author Administrator
 * 
 */
public class MatrixView extends View {
	/** 源图片资源 */
	private Bitmap mBitmap;
	/** 创建Matrix实例 */
	Matrix mMatrix = new Matrix();
	/** 设置倾斜的角度 */
	private float mSkew = 0.0f;
	/** 设置缩放的比率 */
	private float mScale = 1.0f;
	/** 图片资源的宽高 */
	private int mWidth, mHeight;
	/** 判断是否是缩放操作 */
	private boolean isScale = false;
	/**屏幕的宽高*/
	private int mWindowWidth, mWindowHeight;

	public MatrixView(Context context) {
		this(context, null);
	}

	public MatrixView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public MatrixView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// 初始化
		initView(context);
	}

	/***
	 * 初始化
	 * 
	 * @param context
	 */
	private void initView(Context context) {
		// 获得源位图
		mBitmap = ((BitmapDrawable) context.getResources().getDrawable(
				R.drawable.ic_launcher)).getBitmap();
		// 获得位图的宽高
		mWidth = mBitmap.getWidth();
		mHeight = mBitmap.getHeight();
		
	}

	@SuppressLint("DrawAllocation")
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// 重置Matrix
		mMatrix.reset();
		// 判断是否是缩放操作
		if (isScale) {
			// 设置缩放
			mMatrix.setScale(mScale, mScale);
		} else {
			// 设置倾斜
			mMatrix.setSkew(mSkew, 0);
		}
		// 根据bitmap源位图和Matrix创建新的位图
		Bitmap mBitmap2 = Bitmap.createBitmap(mBitmap, 0, 0, mWidth, mHeight,
				mMatrix, true);
		// 绘制
		canvas.drawBitmap(mBitmap2, mMatrix, null);
	}

	/***
	 * 设置倾斜的角度
	 * 
	 * @param skew
	 */
	public void setSkew(float skew, boolean isInvalidate) {
		this.mSkew = skew;
		setInvalidate(isInvalidate);
	}

	/***
	 * 设置缩放的比率
	 * 
	 * @param skew
	 */
	public void setScale(float scale, boolean isInvalidate) {
		this.mScale = scale;
		setInvalidate(isInvalidate);
	}

	/***
	 * 设置是否是缩放
	 * 
	 * @param isScale
	 *            true:缩放;false:倾斜
	 */
	public void setIsScale(boolean isScale) {
		this.isScale = isScale;
	}

	/**
	 * 设置view组件重绘
	 * 
	 * @param isInvalidate
	 */
	private void setInvalidate(boolean isInvalidate) {
		if (isInvalidate) {
			invalidate();
		}
	}

}
2.在Activity中的使用

package com.example.matrixdemo;

import com.example.matrixdemo.view.MatrixView;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

/**
 * 
 * @author Administrator
 *
 */
public class MainActivity extends Activity implements OnClickListener {
	/** 图形的旋转,倾斜变换组件 */
	private MatrixView mMatrixView;
	/** 向左倾斜按钮 */
	private Button skew_left;
	/** 向右倾斜按钮 */
	private Button skew_right;
	/** 放大按钮 */
	private Button scale_up;
	/** 缩小按钮 */
	private Button scale_row;
	/** 倾斜的角度 */
	private float mSkew = 0.0f;
	/** 缩放的比率 */
	private float mScale = 1.0f;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		initEvent();
	}

	/***
	 * 初始化监听事件
	 */
	private void initEvent() {
		skew_left.setOnClickListener(this);
		skew_right.setOnClickListener(this);
		scale_up.setOnClickListener(this);
		scale_row.setOnClickListener(this);
	}

	/***
	 * 初始化组件
	 */
	private void initView() {
		mMatrixView = (MatrixView) findViewById(R.id.matrix_view);
		skew_left = (Button) findViewById(R.id.skew_left);
		skew_right = (Button) findViewById(R.id.skew_right);
		scale_up = (Button) findViewById(R.id.scale_up);
		scale_row = (Button) findViewById(R.id.scale_row);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.skew_left:
			mSkew -= 1;
			mMatrixView.setIsScale(false);
			mMatrixView.setSkew(mSkew, true);
			break;
		case R.id.skew_right:
			mSkew += 1;
			mMatrixView.setIsScale(false);
			mMatrixView.setSkew(mSkew, true);
			break;
		case R.id.scale_up:
			if (mScale < 5) {
				mScale += 0.1;
			} else {
				mScale = 5;
			}
			mMatrixView.setIsScale(true);
			mMatrixView.setScale(mScale, true);
			break;
		case R.id.scale_row:
			if (mScale > 0.5) {
				mScale -= 0.1;
			} else {
				mScale = 0.5f;
			}
			mMatrixView.setIsScale(true);
			mMatrixView.setScale(mScale, true);
			break;
		}
	}
}
3.Activity的布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.matrixdemo.view.MatrixView
        android:id="@+id/matrix_view"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/skew_left"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="向左倾斜" />

        <Button
            android:id="@+id/skew_right"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="向右倾斜" />

        <Button
            android:id="@+id/scale_up"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="放大" />

        <Button
            android:id="@+id/scale_row"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="缩小" />
    </LinearLayout>
</RelativeLayout>

-----------------------------------------------------------------------

下面这个例子,是借助于Bitmap的createBitmap方法,"挖取"源位图的其中一块,在程序中通过定时器控制不断地"挖取"源位图不同位置的块,从而实现背景移动的"假象".

/**
 * 
 */
package com.example.matrixdemo;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;

/**
 * 移动背景
 */
public class MoveBackActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(new MyView(this));
	}

	class MyView extends View {
		/** 记录背景位图的实际高度 */
		final int BACK_HEIGHT = 1700;
		/** 背景位图 */
		private Bitmap mBack;
		/** 飞机位图 */
		private Bitmap mPlane;
		/** 背景图片开始的宽度 */
		final int WIDTH = 320;
		/** 背景图片开始的高度 */
		final int HEIGHT = 440;
		private int startY = BACK_HEIGHT - HEIGHT;

		public MyView(Context context) {
			this(context, null);
		}

		public MyView(Context context, AttributeSet attrs) {
			this(context, attrs, 0);
		}

		public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
			super(context, attrs, defStyleAttr);
			mBack = ((BitmapDrawable) getResources().getDrawable(
					R.drawable.bg02)).getBitmap();
			mPlane = ((BitmapDrawable) getResources().getDrawable(
					R.drawable.hero1)).getBitmap();
			final Handler handler = new Handler(){
				@Override
				public void handleMessage(Message msg) {
					super.handleMessage(msg);
					if(msg.what == 0x123){
						//重新开始移动
						if(startY <= 0){
							startY = BACK_HEIGHT - HEIGHT;
						}else{
							startY -= 3;
						}
					}
					invalidate();
				}
			};
			
			final Timer timer = new Timer();
			timer.schedule(new TimerTask() {
				@Override
				public void run() {
					handler.sendEmptyMessage(0x123);
				}
			}, 0, 100);
			
			
		}
		
		@Override
		protected void onDraw(Canvas canvas) {
			super.onDraw(canvas);
			//根据源位图和Matrix创建新的位图
			Bitmap bitmap = Bitmap.createBitmap(mBack, 0, startY, WIDTH, HEIGHT);
			//绘制新的位图,背景
			canvas.drawBitmap(bitmap, 0, 0,null);
			//绘制飞机
			canvas.drawBitmap(mPlane, 160, 380, null);
		}

	}

}
上面的就是使用Matrix控制进行变换的一些简单描述.
---------------------------------------------------------
欢迎各位评价,提出意见以及建议....

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值