注:一下所有数据都是基于小米Pad调试得来的
屏幕角度说明:
关于屏幕的横竖屏旋转首先要分清屏幕旋转角度和摄像头旋转角度的对应关系(如附图1)
屏幕旋转角度:正常竖屏情况下是0度,顺时针栓转依次为 90,180 270
相机旋转角度:正常竖屏情况下是90度, 顺时针依次为 180,270,0
他们的对应关系相差90度
cameraDegrees = (90+orientation)% 360;
屏幕旋转与摄像头旋转
首先可以通过 mCamera.setDisplayOrientation(degrees); 来设置随着屏幕旋转相机预览的角度
其中参数degrees是当前屏幕状态对应的相机旋转角度,
因为相机成像即预览时捕获的data[]数据是始终获取的横屏数据(这个data是没有角度的,始终如一)即 相机角度为0度的状态, 所以在预览时如果预览的surfaceView有跟着屏幕转动,就要设置相应的相机旋转角度来达到预览效果始终跟屏幕旋转到正确方向。
关于相机预览角度的总结:捕获的raw数据是没有跟随屏幕的旋转而改变的,在没有旋转屏幕时,始终与屏幕保持逆时针90度(顺时针270度)的角度,而一段预览view跟谁屏幕发生旋转 就要设置相机旋转角度以匹配屏幕旋转的预览角度。
摄像头实际成像数据的旋转
方法一:直接对数组旋转
旋转思路:矩阵的转换
参数说明:
data 是摄像头捕获数据转灰度后的数据,因为摄像头捕获数据是YUV格式,这样的格式不能直接用该方法旋转否则会出现错误
width:相机使用像素对应的宽度
height: 相机使用像素对应的高度
// 旋90度
public void getRotation_90(int[] data, int width, int height) {
int len = data.length;
if (len != width * height) {
return;
}
int[] rotation = new int[len];
int index = 0;
for (int i = 0; i < width; i++) {
for (int j = height - 1; j >= 0; j--) {
rotation[index++] = data[j * width + i];
}
}
for (int i = 0; i < len; i++) {
data[i] = rotation[i];
}
rotation = null;
}
// 旋180度
public void getRotation_180(int[] data, int width, int height) {
int len = data.length;
if (len != width * height) {
return;
}
for (int i = 0; i < len / 2; i++) {
int temp = data[i];
data[i] = data[len - 1 - i];
data[len - 1 - i] = temp;
}
}
// 旋270度
public void getRotation_270(int[] data, int width, int height) {
int len = data.length;
if (len != width * height) {
return;
}
int[] rotation = new int[len];
int index = 0;
for (int j = width - 1; j >= 0; j--) {
for (int i = 0; i < height; i++) {
rotation[index++] = data[i * width + j];
}
}
for (int i = 0; i < len; i++) {
data[i] = rotation[i];
}
rotation = null;
}
方法二:通过bitmap来转
注意使用bitmap后 记得recycle()参数说明:
b:将摄像头捕获的图像信息转转化为像素数组之后生成bitmap 相关转化方法