android 解决Camera预览时成像角度错误(与镜像的不符)

本文介绍了解决Android设备上使用前置摄像头时预览画面出现90度旋转的问题。通过调整Camera对象的显示方向参数,确保了预览画面与实际场景保持一致。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

android 解决Camera预览时成像角度错误(与镜像的不符)

问题描述:手机竖直,当启用前摄像头预览实时的影像时,发现实际影像旋转了90度,如下图
这里写图片描述
解决办法:

当调用Camera.open(frontIndex)之后,调用如下函数即可解决问题。

/**
     * @param activity 相机显示在的Activity
     * @param cameraId 相机的ID
     * @param camera   相机对象
     */
    public void setCameraDisplayOrientation(Activity activity, int cameraId, Camera camera) {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }
        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {
            // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }

注:在preview 期间不允许调用该方法

### Android Camera2 API 实现预览拍照功能 #### 初始化CameraManager并打开摄像头设备 为了使用Camera2 API,在应用程序中首先要获取`CameraManager`实例来管理摄像头资源。通过这个管理者可以查询可用的摄像头ID列表,并请求打开特定的摄像头。 ```java String cameraId; CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); try { cameraId = manager.getCameraIdList()[0]; // 获取第一个后置摄像头ID } catch (CameraAccessException e) { Log.e("Error", "Cannot access the camera.", e); } ``` 一旦有了摄像头ID,就可以尝试开启它: ```java manager.openCamera(cameraId, stateCallback, null); ``` 这里`stateCallback`是一个实现了`CameraDevice.StateCallback`接口的对象,用于监听摄像头状态变化事件[^1]。 #### 创建Session配置以设置预览和捕捉目标 当成功打开了摄像头之后,下一步就是创建一个会话(session),这涉及到定义图像读取器(`ImageReader`)作为接收图片数据的目标之一。对于实预览,则需指定表面视图(SurfaceView)或纹理视图(TextureView)作为显示区域。 ```java // 设置TextureView为预览界面 Surface previewSurface = new Surface(textureView.getSurfaceTexture()); CaptureRequest.Builder captureBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); captureBuilder.addTarget(previewSurface); camera.createCaptureSession(Arrays.asList(previewSurface), sessionStateCallback, handler); ``` 上述代码片段展示了如何构建一个针对预览模式的捕获请求,并将其关联至之前提到过的展示面。 #### 处理照片拍摄逻辑 要实现拍照功能,除了常规的预览外还需要额外准备一张静态的照片输出路径——即另一个类型的surface对象,通常由`ImageReader`负责处理最终保存下来的JPEG文件或其他格式的数据流。 ```java final ImageReader reader = ImageReader.newInstance(width, height, format, maxImages); reader.setOnImageAvailableListener(readerListener, backgroundHandler); // 添加到session中的target list里去 captureBuilder.addTarget(reader.getSurface()); ``` 最后一步是在适当的候触发实际的快门动作,可以通过修改之前的builder实例并向当前活跃的session提交新的命令序列完成此操作。 ```java camera.createCaptureSession(Arrays.asList(previewSurface, reader.getSurface()), sessionStateCallback, handler); // 构建拍照请求 CaptureRequest.Builder stillCaptureBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); stillCaptureBuilder.addTarget(reader.getSurface()); // 提交单次拍照请求 session.capture(stillCaptureBuilder.build(), captureCallback, handler); ``` 以上便是利用Camera2 API实现在Android平台上进行相机预览成像的基本流程概述。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值