您的位置:首页 > 移动开发 > Android开发

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

2015-03-28 22:39 351 查看
使用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控制进行变换的一些简单描述.

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

欢迎各位评价,提出意见以及建议....
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: