Android Camera使用总结与那些坑

本文总结了Android Camera模块的开发,包括闪光灯设置、预览分辨率选择和拍照分辨率选择等关键点,并详细阐述了在开发中遇到的坑,如照片分辨率低、旋转问题、应用崩溃等问题及其解决办法,旨在帮助开发者规避这些问题。

写在开头

需求方:上传试卷的时候,用户自己拍的照片有很多问题。如:不清晰、图片歪了、错误图片等。我们要是能够对拍摄照片进行识别处理就好了,能够裁切矫正就更好了,最好可以像二维码扫描一样,直接识别处理~

开发:满足你!

整体框架逻辑

试卷扫描模块,最核心的逻辑就是数据采集、解码识别、图片裁切,再加上对识别结果和裁切结果的处理,就构成了整个模块的主逻辑。整个逻辑的实现如下图所示:

试卷扫描框图

在模块中,除了UI线程,还开启了一个Deocde线程,用来处理图片的解码识别和裁切。这么做的原因是因为对于图片数据的处理,是比较耗时的,如果在UI线程处理,会有ANR的风险。同时采用这种处理方式,整个模块的流畅性也更加好,且模块的结构更加清晰。
那么线程之间是如何交互的呢?这里模块中是采用了最常用的Handler消息传递机制。因为通过Handler的Message可以在线程间传递较大的图片数据(注意如果在Intent的Bundle中传递较大的数据,会崩溃报错)。请看下面这段代码:

  @Override
  public void run() {
    Looper.prepare();
    handler = new DecodeHandler(activity);
    handlerInitLatch.countDown();
    Looper.loop();
  }

上面这个方法是DecodeThread的run方法,在方法中,我们初始化了当前线程对应的Handler对象DecodeHandler。而DecodeHandler初始化是需要传入当前主线程的上下文activity,通过activity我们可以拿到主线程的Handler对象。这样的话主线程和解码线程就建立了联系,它们之间就可以方便得进行消息传递了。最终实现的模块采集界面如下所示:

扫码界面

模块开发相关实现

整个扫码拍照模块的逻辑比较琐碎,就不一一说明了。以下是整理的几个开发中比较关键的点和Camera硬件开发一些经验,在这里做记录,避免以后重复造轮子。

闪光灯设置

  • 开启闪光灯
public void turnOnFlash(){
        if(camera != null){
            try {
                Camera.Parameters parameters = camera.getParameters();
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                camera.setParameters(parameters);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
  • 关闭闪光灯
  public void turnOffFlash(){
        if(camera != null){
            try {
                Camera.Parameters parameters = camera.getParameters();
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                camera.setParameters(parameters);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

预览图片分辨率选择

预览图片的分辨率选择逻辑是:有1920*1080则选之,否则选硬件支持的最大的分辨率,且满足图片比例为16:9

private static Point findBestPreviewSizeValue(List<Camera.Size> sizeList, Point screenResolution) {
      int bestX = 0;
      
<think> 我们正在讨论Android Camera HAL层开发的要点。根据引用内容,HAL层是连接Android框架和底层驱动的关键部分。从引用[1][2]中我们可以知道,HAL3是目前的主流,其核心是`process_capture_request`。引用[4]提到,HAL层由各个厂商自己实现,比如Qualcomm的CamX和MTK的Hal3架构。引用[5]指出,Android 8.0之后大多采用HAL3架构。 因此,回答要点应包括: 1. 遵循Google的接口规范(如camera_module_t, camera_device_t等结构体)。 2. HAL3的核心是process_capture_request,它处理捕获请求。 3. 厂商需要实现自己的架构(如CamX或MTK Hal3)。 4. 需要处理底层驱动的交互(如V4L2)。 同时,我们还需要考虑开发中的实际要点,比如模块初始化、请求处理流程、元数据配置等。 现在组织回答: 一、遵循Google的HAL接口规范 二、理解HAL3的核心机制(请求/结果) 三、厂商特定架构的实现要点 四、底层驱动的交互 五、性能优化和调试 最后,生成相关问题。 </think>### Android Camera HAL层开发要点详解 Android Camera HAL(硬件抽象层)是连接框架底层驱动的核心枢纽,开发要点如下: #### 一、遵循HAL接口规范 1. **核心结构体实现** - **`camera_module_t`**:模块入口点,定义`get_number_of_cameras()`、`get_camera_info()`等基础接口,用于枚举设备[^1][^2]。 - **`camera_device_t`**:设备实例,在HAL3中需实现`process_capture_request()`作为核心调度单元(取代HAL1的`start_preview()`等)[^2][^5]。 - **示例代码结构**: ```c static camera_module_t HAL_MODULE_INFO_SYM = { .common = { /* 模块版本信息 */ }, .get_number_of_cameras = get_camera_count, .get_camera_info = get_camera_info, }; ``` 2. **HAL3架构适配** - **请求-响应模型**:通过`process_capture_request()`接收框架的捕获请求(包含配置参数),异步返回结果(图像数据+元数据)[^1][^5]。 - **元数据控制**:使用`camera_metadata_t`传递3A(AF/AE/AWB)参数、分辨率等配置,需解析并映射到底层驱动[^1][^4]。 --- #### 二、平台适配关键点 1. **厂商架构集成** - **高通平台**:CamX架构(新)或mm-Camera(旧),需实现`ChiOverride`扩展接口[^4]。 - **联发科平台**:MTK Hal3架构,需适配管道线(Pipeline)调度和ISP处理模块[^3]。 2. **底层驱动交互** - **V4L2/Kernel驱动**:通过`ioctl`调用控制传感器(如设置分辨率`VIDIOC_S_FMT`)和图像处理(如`VIDIOC_REQBUFS`申请缓冲区)[^4][^5]。 - **关键流程**: ```mermaid graph LR A[Framework] -->|capture_request| B(HAL3) B -->|ioctl VIDIOC_QBUF| C[V4L2 Driver] C -->|DMA传输| D[Sensor] D -->|图像数据| C C -->|ioctl VIDIOC_DQBUF| B B -->|metadata+图像| A ``` --- #### 三、开发实践要点 1. **初始化资源管理** - **动态资源分配**:按需分配图像处理管道(如ISP、JPEG编码器),避免静态资源浪费[^3][^5]。 - **热插拔支持**:实现`torch_mode_status_change()`通知框架摄像头状态变化[^2]。 2. **性能优化** - **零拷贝设计**:通过`Gralloc`共享内存传递图像数据,减少内存复制开销[^5]。 - **延迟控制**:异步处理3A算法,确保`process_capture_request()`响应时间 < 30ms[^1][^3]。 3. **调试兼容性** - **CTS/GTS验证**:通过`Camera ITS`测试套件验证HAL接口兼容性[^3]。 - **日志追踪**:使用`CAMERA_HAVE_MTK_LOG`(MTK平台)记录流水线状态[^3]。 --- #### 四、避指南 1. **常见问题** - **元数据同步**:若未及时返回`ANDROID_SENSOR_TIMESTAMP`会导致帧率不稳。 - **版本兼容**:HAL需同时支持`HAL3.7`(Android 12)和`HAL3.5`(Android 10)[^1][^5]。 2. **最佳实践** - **复用参考实现**:基于`android.hardware.camera.provider@2.4-service`模板开发[^2][^4]。 - **模块化设计**:分离传感器控制、ISP处理、元数据生成模块[^3][^5]。 > **开发要点总结**:**规范接口 → 平台适配 → 性能优化 → 兼容性验证**。HAL3开发核心在于高效实现`process_capture_request()`并优化数据流路径[^1][^5]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值