Android View之Camera

(一)Camera概述

本篇中的Camera是graphic包下的Camera,是专业给View拍照的(Camera)相机。
View的摄像机默认位置在屏幕左上角(0, 0, -8),而且距离屏幕有一段距离。

几个概念:
①、Camera使用的三维(3D)坐标系是左手坐标系。即左手手臂指向的是X轴正方向,
四指弯曲指向的是Y轴正方向(刚好与2D的Y轴正方向相反),展开的大拇指指向的是Z轴正方向。

②、三维投影是将三维空间中的点映射到二维平面上的方法。

(二)Camera的用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 保存当前状态
camera.save();
// 恢复当前状态
camera.restore();


// 设置Camera在左手坐标系(3D)的对应位置。
// 注意:这里Camera平移location一个单位相当于translate 72像素。
camera.setLocation(float x, float y, float z);
// 获取Camera在左手坐标系(3D)的对应位置。
float locationX = camera.getLocationX();
float locationY = camera.getLocationY();
float locationZ = camera.getLocationZ();


// 计算当前矩阵对应的状态并赋值给参数matrix。
camera.getMatrix(Matrix matrix);
// 计算当前矩阵对应的状态并将计算后的矩阵应用到指定的canvas上。
camera.applyToCanvas(Canvas canvas);


// x、将Camera沿X轴正方向平移(与Matrix在沿X轴方向平移一致)。
// y、将Camera沿Y轴正方向平移(注意这里指向的正上方,与Matrix在沿Y轴方向平移相反)。
// z、将Camera沿Z轴正方向平移(近大-Z 远小-XY、视线相交)。
camera.translate(float x, float y, float z);

// 注意:Camera旋转中心默认是坐标原点。
// 将Camera同时绕X,Y,Z轴旋转,旋转角度为(x,y,z)。
camera.rotate(float x, float y, float z);
// 将Camera同时绕X轴旋转,旋转角度为deg。
camera.rotateX(float deg);
// 将Camera同时绕Y轴旋转,旋转角度为deg。
camera.rotateY(float deg);
// 将Camera同时绕Z轴旋转,旋转角度为deg。
camera.rotateZ(float deg);

(三)Camera的实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/**
* Camera 3D旋转动画(绕图片中心旋转)
* <p>
* 参考:https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/src/com/example/android/apis/animation/Rotate3dAnimation.java
* <p>
* http://www.gcssloop.com/customview/matrix-3d-camera
* <p>
* 动画之间旋转视图在Y轴上的两个指定角度。
* 这个动画还增加了平移在Z轴(深度)改善效果。
*
* @author [*昨日重现*] lhy_ycu@163.com
* @since version 1.0
*/
public class Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
private float mDensity;// Pixel density

/**
* @param context context
* @param fromDegrees the start angle of the 3D rotation
* @param toDegrees the end angle of the 3D rotation
* @param centerX the X center of the 3D rotation
* @param centerY the Y center of the 3D rotation
* @param reverse true if the translation should be reversed, false otherwise
*/
public Rotate3dAnimation(Context context, float fromDegrees, float toDegrees,
float centerX, float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
mDensity = context.getResources().getDisplayMetrics().density;
}

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

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
// 旋转角度 = 起始角度 + 增长角度
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
DebugLog.e("interpolatedTime:" + interpolatedTime + ", degrees:" + degrees);

final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;

final Matrix matrix = t.getMatrix();

camera.save();
// Adds a translation on the Z axis (depth) to improve the effect
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
camera.getMatrix(matrix);
DebugLog.e("matrix---------------1" + matrix.toShortString());
camera.restore();

// 修改MPERSP_0、MPERSP_1的值
float[] values = new float[9];
matrix.getValues(values);
values[6] = values[6] / mDensity;
values[7] = values[7] / mDensity;
matrix.setValues(values);

// 调节中心点的位置
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);

DebugLog.e("matrix---------------2:" + matrix.toShortString());
}
}


/**
// 测试3D动画
final float centerX = img.getWidth() / 2.0f;
final float centerY = img.getHeight() / 2.0f;
Rotate3dAnimation animation = new Rotate3dAnimation(MainActivity.this, 0, 180, centerX, centerY, 0, true);
animation.setDuration(2000L);
animation.setFillAfter(true);// 保持旋转动画结束后的位置
animation.setInterpolator(new LinearInterpolator());
img.startAnimation(animation);
*/
Hawky wechat
欢迎订阅我的微信公众号
坚持原创技术分享,您的支持将鼓励我继续创作!

分享