Camera2API 实现重力感应四个方向调试相机预览
文章目录
需求
Camera2 相机预览实现四个重力感应方向预览方向正常
场景
- 实际有个客户需求,用到了四个方向的重力感应,但是之前的工程代码只有两个方向,导致屏幕无法四个方向正常显示
- 相机预览两个重力感应方向已经满足了需求,但是客户重力感应模块、板卡 实际物理装配时候不可能按照要求装配的,不同厂家的磨具不一样导致板卡方向装配不一样。基于这样的实际情况,软件就需要适配四个方向,两个重力感应预览方向就无法满足实际要求了。
- 实际产品案例:监控、HDMIN、车载Camera…
需求实现
setAspectRatio 设置显示长宽
设置显示组件长宽
textureView.setAspectRatio(width, height)
private void setupCamera(int width, int height) {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
for (String cameraId : manager.getCameraIdList()) {
...............
int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.d(TAG, "setupCamera: ORIENTATION_LANDSCAPE " + mPreviewSize.getWidth() + " x " + mPreviewSize.getHeight());
textureView.setAspectRatio(1920, 1080);
} else {
textureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth());
Log.d(TAG, "setupCamera: ORIENTATION_PORT " + mPreviewSize.getWidth() + " x " + mPreviewSize.getHeight());
}
break;
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
使用位置:在View 组件流传递过来时候, onSurfaceTextureAvailable 方法中,去设置 setupCamera
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
setupCamera(width, height);
configureTransform(width, height);
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
configureTransform(width, height);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
postScale postRotate 设置缩放和旋转
比如长宽肯定是1920*1080,根据实际产品长宽进行设置,但是如果是竖屏状态下,还是需要这个图像输出流的比例数出来,那么就必须进行缩放,才能完全显示出来的。
补充下基本知识点:
Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。
set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉,这也就意味着你对同一个矩阵先调用setScale,再调用setTranslate,那么矩阵只会执行Translate的操作,前面的scale操作是无效的。
post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。例如,要将一个图片先缩放,再平移则可以通过:
同样的道理,如上面设置显示长宽的后面就需要又缩放和旋转逻辑了, 输出流的地方是不会变的,那么接收的地方就需要根据实际情况如重力感应和物理场景【竖屏-横屏】进行流显示的变化了->缩放、旋转操作
onSurfaceTextureAvailable -> configureTransform(width, height) -> Configuration config = getResources().getConfiguration()【根据重力感应方向,计算缩放比例和旋转角度及选择方向了】
核心代码如下:
private void configureTransform(int viewWidth, int viewHeight) {
if (null == textureView || null == mPreviewSize) {
return;
}
int rotation = getWindowManager().getDefaultDisplay().getRotation();
Configuration config = getResources().getConfiguration();
if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
Log.d(TAG, "configureTransform: ORIENTATION_PORTRAIT");
if(Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation){
isRotation = true;
}
} else if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.d(TAG, "configureTransform: ORIENTATION_LANDSCAPE");
if(Surface.ROTATION_0 == rotation || Surface.ROTATION_180 == rotation){
isRotation = true;
}
}
Log.d(TAG, "configureTransform: isRotation = "+isRotation);
if(isRotation){
rotation = rotation + 1;
if(rotation > 3){
rotation = rotation - 3;
}
}
Log.d(TAG," aaaaaaaaaaaa rotation:"+rotation);
Matrix matrix = new Matrix();
RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
float centerX = viewRect.centerX();
float centerY = viewRect.centerY();
if (Surface.ROTATION_90 == rotation) {
bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
float scale = Math.max(
(float) viewHeight / mPreviewSize.getHeight(),
(float) viewWidth / mPreviewSize.getWidth());
matrix.postScale(scale, scale, centerX, centerY);
matrix.postRotate(90 * (rotation - 2), centerX, centerY);
Log.d(TAG," 00000000000000 ");
}else if ( Surface.ROTATION_270 == rotation) {
bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
float scale = Math.max(
(float) viewHeight / mPreviewSize.getHeight(),
(float) viewWidth / mPreviewSize.getWidth());
matrix.postScale(scale, scale, centerX, centerY);
matrix.postRotate(270, centerX, centerY);
Log.d(TAG," bbbbbbbbbbbbbbbb ");
} else if (Surface.ROTATION_180 == rotation) {
float scale = (float)1080/ 1920;
Log.d(TAG, "configureTransform: rizhi xianshi port state scale:"+scale+" centerX:"+centerX+" centerY:"+centerY);
matrix.postScale(scale, scale, centerX, centerY);
textureView.setRotation(270f);
Log.d(TAG, "configureTransform: "+" centerX:"+centerX+" centerY:"+centerY);
Log.d(TAG," 111111111111111 ");
}else if(Surface.ROTATION_0 == rotation){
float scale = (float)1080/ 1920;
Log.d(TAG, "configureTransform: rizhi xianshi port state scale:"+scale+" centerX:"+centerX+" centerY:"+centerY);
matrix.postScale(scale, scale, centerX, centerY);
textureView.setRotation(270f);
Log.d(TAG," 222222222222222222 ");
}
textureView.setTransform(matrix);
}
manager.openCamera 打开相机
打开相机就是一个比较常规操作了,如上显示组件 已经准备好,进行了算转和缩放操作,就是显示组件已经设置好了参数,接下来就打开相机,让流数据进来。
打开相机基本代码如下:
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
setupCamera(width

最低0.47元/天 解锁文章
2567

被折叠的 条评论
为什么被折叠?



