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

来源:互联网 发布:logo图形设计软件 编辑:程序博客网 时间:2024/06/18 10:27

使用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")@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 重置MatrixmMatrix.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;@Overrideprotected 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);}@Overridepublic 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 {@Overrideprotected 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(){@Overridepublic 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() {@Overridepublic void run() {handler.sendEmptyMessage(0x123);}}, 0, 100);}@Overrideprotected 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控制进行变换的一些简单描述.
---------------------------------------------------------
欢迎各位评价,提出意见以及建议....

0 0
原创粉丝点击