Android中Matrix用法实例分析

这篇文章主要介绍了Android中Matrix用法,以实例形式分析了Matrix矩阵运算的常用技巧,具有一定参考借鉴价值,需要的朋友可以参考下

本文实例讲述了Android中Matrix用法。分享给大家供大家参考,具体如下:

Matrix ,中文里叫矩阵,高等数学里有介绍,在图像处理方面,主要是用于平面的缩放、平移、旋转等操作。

首先介绍一下矩阵运算。加法和减法就不用说了,对应位相加就好。图像处理,主要用到的是乘法 。下面是一个乘法的公式:

在 Android 里面, Matrix 由 9 个 float 值构成,是一个 3*3 的矩阵。如下图:

解释一下,上面的sinX 和cosX ,表示旋转角度的cos 值和sin值,注意,旋转角度是按顺时针方向计算的。 translateX 和 translateY 表示 x 和 y 的平移量。 scale 是缩放的比例, 1 是不变, 2 是表示缩放 1/2 。

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)点来进行。

特别注意:

Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。

set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。

post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。

镜面效果:

倒影效果:

图片的合成(水印):

不多说了,直接上代码了。

MainActivity.java里的主要代码如下:

package net.loonggg.testmatrix; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.os.Bundle; import android.view.Window; import android.widget.ImageView; public class MainActivity extends Activity {   private ImageView iv1, iv2;   private Canvas canvas;   private Paint paint;   @Override   protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     requestWindowFeature(Window.FEATURE_NO_TITLE);     setContentView(R.layout.activity_main);     iv1 = (ImageView) findViewById(R.id.iv1);     iv2 = (ImageView) findViewById(R.id.iv2);     Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(),         R.drawable.weibo);     Bitmap updateBitmap = Bitmap.createBitmap(bitmap1.getWidth() * 2,         bitmap1.getHeight() * 2, bitmap1.getConfig());     canvas = new Canvas(updateBitmap);     paint = new Paint();     paint.setColor(Color.BLACK);     Matrix matrix = new Matrix();     // setMirrorOne(bitmap1, matrix);     // setInvertedImage(bitmap1, matrix);     // setBaseChange(matrix);     canvas.drawBitmap(bitmap1, matrix, paint);     setImageSynthesis(matrix);     iv1.setImageBitmap(bitmap1);     iv2.setImageBitmap(updateBitmap);   }   /**    * 还有一些基本变化    */   private void setBaseChange(Matrix matrix) {     // matrix.setRotate(60);// 这是旋转多少度     // matrix.setRotate(degrees, px, py);//这个方法是以哪个点为中心进行旋转多少度     // matrix.setSkew(kx, ky);//设置倾斜,以x轴倾斜,还是y轴     // 倾斜x和y轴,以(100,100)为中心。     // matrix.postSkew(0 .2f, 0 .2f, 100 , 100 );     // matrix.setScale(0.5f, 1);//缩放宽度变为原来的一半,高度不变   }   /**    * 设置倒影效果    *    * @param bitmap1    * @param matrix    */   private void setInvertedImage(Bitmap bitmap1, Matrix matrix) {     matrix.setScale(1, -1);     matrix.postTranslate(0, bitmap1.getHeight());   }   /**    * 设置镜面效果方法一    *    * @param bitmap1    * @param matrix    */   private void setMirrorOne(Bitmap bitmap1, Matrix matrix) {     matrix.setTranslate(bitmap1.getWidth(), 0);// 这个是移动     matrix.preScale(-1, 1);   }   // ---------------------------------------------------------   /**    * 解释:镜面效果方法一和二的区别:    * 不知道大家看没看出来,其实这两种方法的效果是一样的,只不过是设置步骤不一样,post是后乘,当前的矩阵乘以参数给出的矩阵    * 。可以连续多次使用post,来完成所需的整个变换。 pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。    * 可以连续多次使用post    * ,来完成所需的整个变换,但是不可以连续使用set来完成矩阵的整个变换,为什么呢?set是直接设置Matrix的值,每次set一次    * ,整个Matrix的数组都会变掉,第一次可以使用set,之后的变换必须换成post或者pre,也可以一直用post也行    */   // ---------------------------------------------------------   /**    * 设置镜面效果方法二    *    * @param bitmap1    * @param matrix    */   private void setMirrorTwo(Bitmap bitmap1, Matrix matrix) {     matrix.setScale(-1, 1);     matrix.postTranslate(bitmap1.getWidth(), 0);   }   /**    * 设置图片的合成    *    * @param matrix    */   private void setImageSynthesis(Matrix matrix) {     Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(),         R.drawable.ic_launcher);     // 设置图片合成时的各种模式     paint.setXfermode(new PorterDuffXfermode(Mode.DARKEN));     // 图片的合成很简单,就是再以bitmap2为基图往目标图片上画一次     canvas.drawBitmap(bitmap2, matrix, paint);   } }

布局文件的代码如下:

       

希望本文所述对大家Android程序设计有所帮助。

更多相关文章

  1. android studio设置Tab为四空格缩进
  2. 当你的Android(安卓)Studio 设置No proxy不起作用时,该怎么做?
  3. android 系统权限大全
  4. Android(安卓)UI 设计——TextView 控件
  5. ubuntu下android开发环境配置及常用设置
  6. 一起学opengl android
  7. android 动画分析
  8. Android(安卓)学习笔记(二七):Menu
  9. android背景优化

随机推荐

  1. Android(安卓)运行崩溃找不到so包解决方
  2. android实现发短信功能
  3. android左右滑动翻页查看图片
  4. Android 疑难问题讨论及面试题
  5. Android Button使用,ArrayList使用练习
  6. Android valueAnimator和ObjectAnimator
  7. android 4.4 phone 主叫和被动呼叫的流程
  8. android 通知 手机 媒体 数据库 更新
  9. Android(安卓)ListView拖动时背景颜色会
  10. Android读写文件示例