android.graphics.Camera 仿3D效果

在Android SDK中有两种Camera classes,一个是 android.hardware.Camera,这是用来操控相机功能的类。另一个是 android.graphics.Camera,这个类别能帮我们做些什么事呢?

Camera就像一个摄像机,一个物体在原地不动,然后我们带着这个摄像机四处移动,在摄像机里面呈现出来的画面,就会有立体感,就可以从各个角度观看这个物体。
        它有旋转、平移的一系列方法,实际上都是在改变一个Matrix对象,一系列操作完毕之后,我们得到这个Matrix,然后画我们的物体,就可以了。

android.graphics.Camera 是一个可以让你将 2D 物件在 3D 空间中移动,并将在其移动后的结果画在屏幕上的类别。

打开api说明文件

  1. //Public Constructors   

   2.   Camera()  

       创建一个新的摄像头,空的转换

   3. //Public Methods  

   4.   void  applyToCanvas(Canvas canvas)  

       计算对应当前转换矩阵,并将其应用到指定的画布上。

   5.   float  dotWithNormal(float dx, float dy, float dz)  

   6.   void  getMatrix(Matrix matrix)  

计算对应当前转换矩阵,并将其复制到所提供的矩阵对象。

   7.   void  restore()  

Restores the saved state, if any.
恢复保存的状态,如果有的话。

8.  void rotate(float x, float y, float z)    

Applies a rotation transform around all three axis.
适用于所有三个轴旋转变换。

8.   void  rotateX(float deg)  

Applies a rotation transform around the X axis.
适用于绕X轴旋转变换。

   9.   void  rotateY(float deg)  

Applies a rotation transform around the Y axis.
适用于绕Y轴旋转变换。

  10.   void  rotateZ(float deg)  

Applies a rotation transform around the Z axis.

适用于绕Z轴旋转变换。

  11.   void  save()  

Saves the camera state.
12. setLocation(float x, float y, float z)
Sets the location of the camera.
设置摄像头的位置。

  13.   void  translate(float x, float y, float z)  

Applies a translation transform on all three axis.
适用于所有三个轴的翻译转换。

在 Android ,要做出 3D 的效果,你当然可以用 OpenGL 的函式。不过,如果你需要更快的显示速度,或者只是要做个简单的 3D 特效,

那千万不要忘了这个 android.graphics.Camera。


package com.xxx;

import android.content.Context;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.Transformation;
import android.widget.Gallery;
import android.widget.ImageView;

public class GalleryFlow extends Gallery {

	private Camera mCamera = new Camera();//相机类
    private int mMaxRotationAngle = 80;//最大转动角度
    private int mMaxZoom = -300;最大缩放值
    private int mCoveflowCenter;//半径值
    public GalleryFlow(Context context) {
        super(context);
        Log.d("tag", "1");
        //支持转换 ,执行getChildStaticTransformation方法
        this.setStaticTransformationsEnabled(true);
    }
    public GalleryFlow(Context context, AttributeSet attrs) {
        super(context, attrs);
        Log.d("tag", "2");
        this.setStaticTransformationsEnabled(true);
    }
    public GalleryFlow(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        Log.d("tag", "3");
        this.setStaticTransformationsEnabled(true);
    }
    public int getMaxRotationAngle() {
        return mMaxRotationAngle;
    }
    public void setMaxRotationAngle(int maxRotationAngle) {
        mMaxRotationAngle = maxRotationAngle;
    }
    public int getMaxZoom() {
        return mMaxZoom;
    }
    public void setMaxZoom(int maxZoom) {
        mMaxZoom = maxZoom;
    }
    private int getCenterOfCoverflow() {
        return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
                        + getPaddingLeft();
    }
    private static int getCenterOfView(View view) {
        Log.d("tag", "view left :"+view.getLeft());
        Log.d("tag", "view width :"+view.getWidth());
        return view.getLeft() + view.getWidth() / 2;
    }
   
   
   //控制gallery中每个图片的旋转(重写的gallery中方法)
    @Override
    protected boolean getChildStaticTransformation(View child, Transformation t) { 
        //取得当前子view的半径值
        final int childCenter = getCenterOfView(child);
        Log.d("tag", "childCenter:"+childCenter);
        final int childWidth = child.getWidth();
        //旋转角度
        int rotationAngle = 0;
        //重置转换状态
        t.clear();
        //设置转换类型
        t.setTransformationType(Transformation.TYPE_MATRIX);
        //如果图片位于中心位置不需要进行旋转
        if (childCenter == mCoveflowCenter) {
            transformImageBitmap((ImageView) child, t, 0);
        } else {
            //根据图片在gallery中的位置来计算图片的旋转角度
            rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
            Log.d("tag", "rotationAngle:"+rotationAngle);
            //如果旋转角度绝对值大于最大旋转角度返回(-mMaxRotationAngle或mMaxRotationAngle;)
            if (Math.abs(rotationAngle) > mMaxRotationAngle) {
                rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;
            }
            transformImageBitmap((ImageView) child, t, rotationAngle);
        }
        return true;
    }
    
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        mCoveflowCenter = getCenterOfCoverflow();
        super.onSizeChanged(w, h, oldw, oldh);
    }
    
    private void transformImageBitmap(ImageView child, Transformation t,
                    int rotationAngle) {
        //对效果进行保存
        mCamera.save();
        final Matrix imageMatrix = t.getMatrix();
        //图片高度
        final int imageHeight = child.getLayoutParams().height;
        //图片宽度
        final int imageWidth = child.getLayoutParams().width;
       
        //返回旋转角度的绝对值
        final int rotation = Math.abs(rotationAngle);
       
        // 在Z轴上正向移动camera的视角,实际效果为放大图片。
        // 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。
        mCamera.translate(0.0f, 10.0f, 200.0f);// X值越大图片越靠右Y值越大是图片位置越高Z值越高图片越缩小
        // As the angle of the view gets less, zoom in
        if (rotation < mMaxRotationAngle) {
            float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
            mCamera.translate(0.0f, 0.0f, zoomAmount);
        }
        // 在Y轴上旋转,对应图片竖向向里翻转。
        // 如果在X轴上旋转,则对应图片横向向里翻转。
        mCamera.rotateY(rotationAngle);
        mCamera.getMatrix(imageMatrix);
      //以图片的中心点为旋转中心,如果不加这两句,就是以(0,0)点为旋转中心
        imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
        imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
        mCamera.restore();//恢复
    }

}


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值