Android Camera 3D效果

版本:1.0
日期:2014.4.14
版权:© 2014 kince 转载注明出处

一、概念

 在Android中要想实现3D效果,第一个想到的应该就是OpenGL ES,因为在很多基础教材中几乎都提到了它。但是其使用起来还是稍微麻烦一些,而且它也主要用在游戏方面,那在应用方面有没有更好的选择呢?答案是肯定的,使用Camera类就可以完成3D效果。它有旋转、平移的一系列方法,实际上都是在改变一个Matrix对象,一系列操作完毕之后,我们得到这个Matrix,然后画我们的物体,就可以了。实际上内部机制还是opengl,不过大大简化了使用。
  这么说可能有些朋友会有疑问,Camera不是相机方面的么,其实看完下面的图片就明白了。
   不错,Camera在hardware包里面是负责相机方面的;在graphics包里面是图形方面的,不要混淆了。因此接下来主要说一下后者的一些用法,Camera用来计算3D转换、生成矩阵,然后应用在画布上。它的构造方法只有一个不带参数的Camera(),用于实例化一个带有空的转换的Camera。
  Camera的坐标系是左手坐标系。如下图所示:
  
 可以想象一下你Android设备平整的放在桌面上,X轴是手机的水平方向,Y轴是手机的竖直方向,Z轴是垂直于手机向里的那个方向。下面是一些细节:

1、camera位于坐标点(0,0),也就是视图的左上角;

2、camera.translate(10,20,30)的意思是把观察物体右移10,上移20,向前移30(即让物体远离camera,这样物体将会变小);

3、camera.rotateX(45)的意思是绕X轴顺时针旋转45度。举例来说,如果物体中间线和X轴重合的话,绕X轴顺时针旋转45度就是指物体上半部分向里翻转,下半部分向外翻转;

4、camera.rotateY(45)的意思是绕Y轴顺时针旋转45度。举例来说,如果物体中间线和Y轴重合的话,绕Y轴顺时针旋转45度就是指物体左半部分向外翻转,右半部分向里翻转;

5、camera.rotateZ(45)的意思是绕Z轴逆时针旋转45度。举例来说,如果物体中间线和Z轴重合的话,绕Z轴顺时针旋转45度就是物体上半部分向左翻转,下半部分向右翻转。
它的方法比较少,而且也都比较容易理解,但是都比较常用:
  
   接下来说一下各个方法的用法:
1、applyToCanvas(Canvas canvas)
    根据当前的变换计算出相应的矩阵,然后应用到制定的画布上去,注意是由画布来设置矩阵的。

2、rotateX(float degree)
     绕着x轴旋转degree个度数

3、rotateY(float degree)
     绕着y轴旋转degree个度数

4、rotateZ(float degree)
     绕着z轴旋转degree个度数

5、translate(float x,float y,float z) 
     在x、y、z坐标轴上执行变换操作

6、save()和restore()
     保存原状态,操作完之后,恢复到原状态

 除此之外,还要有一个类来配合Camera来使用,那就是Matrix。Matrix用于处理三维的矩阵坐标变换,也常用于图片的处理。Matrix提供了translate(平移)、rotate(旋转)、scale(缩放)、skew(倾斜)四种操作,这四种操作的内部实现过程都是通过matrix.setValues(…)来设置矩阵的值来达到变换图片的效果。Matrix的每种操作都有set、pre、post三种操作,set是清空队列再添加,pre是在队列最前面插入,post是在队列最后面插入。除了translate,其他三种操作都可以指定中心点。

二、实例
     1、翻转
  比如要实现一个图片翻转的效果,可以这样来写:

  1. import android.graphics.Camera;  
  2. import android.graphics.Matrix;  
  3. import android.view.animation.Animation;  
  4. import android.view.animation.Transformation;  
  5.   
  6. public class Rotate3DAnimation extends Animation {  
  7.      // 3d rotate  
  8.      private float mFromDegrees;  
  9.      private float mToDegrees;  
  10.      private float mCenterX;  
  11.      private float mCenterY;  
  12.       
  13.      private Camera mCamera;  
  14.       
  15.     public Rotate3DAnimation(float fromDegrees, float toDegrees)  
  16.     {  
  17.          mFromDegrees = fromDegrees;  
  18.          mToDegrees = toDegrees;  
  19.     }  
  20.   
  21.      @Override  
  22.      public void initialize(int width, int height, int parentWidth,  
  23.                int parentHeight)  
  24.      {  
  25.           super.initialize(width, height, parentWidth, parentHeight);  
  26.           mCenterX = width / 2;  
  27.           mCenterY = height / 2;  
  28.           mCamera = new Camera();  
  29.      }  
  30.   
  31.      @Override  
  32.      protected void applyTransformation(float interpolatedTime, Transformation t)  
  33.      {  
  34.            
  35.           final float fromDegrees = mFromDegrees;  
  36.           float degrees = fromDegrees + (mToDegrees - mFromDegrees) * interpolatedTime;  
  37.            
  38.           final Matrix matrix = t.getMatrix();  
  39.            
  40.           mCamera.save();  
  41.            
  42.           mCamera.rotateY(degrees);  
  43.           mCamera.getMatrix(matrix);  
  44.           mCamera.restore();  
  45.           //  
  46.           matrix.preTranslate(-mCenterX, -mCenterY);  
  47.           matrix.postTranslate(mCenterX, mCenterY);  
  48.      }  
  49. }  
import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.Transformation;

public class Rotate3DAnimation extends Animation {
     // 3d rotate
     private float mFromDegrees;
     private float mToDegrees;
     private float mCenterX;
     private float mCenterY;

     private Camera mCamera;

    public Rotate3DAnimation(float fromDegrees, float toDegrees)
    {
         mFromDegrees = fromDegrees;
         mToDegrees = toDegrees;
    }

     @Override
     public void initialize(int width, int height, int parentWidth,
               int parentHeight)
     {
          super.initialize(width, height, parentWidth, parentHeight);
          mCenterX = width / 2;
          mCenterY = height / 2;
          mCamera = new Camera();
     }

     @Override
     protected void applyTransformation(float interpolatedTime, Transformation t)
     {

          final float fromDegrees = mFromDegrees;
          float degrees = fromDegrees + (mToDegrees - mFromDegrees) * interpolatedTime;

          final Matrix matrix = t.getMatrix();

          mCamera.save();

          mCamera.rotateY(degrees);
          mCamera.getMatrix(matrix);
          mCamera.restore();
          //
          matrix.preTranslate(-mCenterX, -mCenterY);
          matrix.postTranslate(mCenterX, mCenterY);
     }
}
   看代码,首先重载了initialize()方法,在里面初始化中间坐标mCenterX、mCenterY 以及实例化Camera对象,initialize()是一个回调函数告诉Animation目标View的大小参数,在这里可以初始化一些相关的参数,例如设置动画持续时间、设置Interpolator、设置动画的参考点等。applyTransformation (float interpolatedTime, Transformation t)函数来实现自定义动画效果,在绘制动画的过程中会反复的调用applyTransformation 函数。通过参数Transformation 来获取变换的矩阵(matrix),final Matrix matrix = t.getMatrix(),通过改变矩阵就可以实现各种复杂的效果。Camera类是用来实现绕Y轴旋转后透视投影的,首先通过t.getMatrix()取得当前的矩阵,然后camera.rotateY对矩阵进行旋转。preTranslate函数是在旋转前移动而postTranslate是在旋转完成后移动,主要作用是让对象围绕自己的中心二旋转。

三、总结
      可以看到,要想实现3D效果,还要借助Animation类的配合,因为这个类正是动画类,提供了对象变换的平台。在Android apidemo中也有一个3D效果的程序,类名叫Rotate3dAnimation ,上面的代码真是这个Rotate3dAnimation的简化版本。本文介绍的3D效果,只是翻转的效果,其实还有很多其他方面的,比如折叠等。以后会继续介绍,谢谢关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值