Android Camera 系列目录

  1. 搭建Camera开发项目
  2. Android Camera API
    • Camera API使用指南
    • Camera 高级特性——手动对焦
    • Android Camera 高级特性——闪光灯、抗闪烁、场景
    • Camera性能优化
  3. Android Camera2 API
    • Camera2 API使用指南
    • Camera2硬件兼容级别
    • Camera2拉伸问题
    • Camera2高级特性
    • Camera2源代码分析
  4. 相机模块设计

1. Camera简介

虽然前文说道Android在5.0之后就推出了Camera2 API,但是各个厂家的基本未适配,导致目前市场上大部分机型使用的仍然是Camera1 API。

PS:Android 9.0 Google强制要求各个平台厂商(高通/MTK/华为等)支持Camera2,不再兼容Camera1。

Camera API是Android非常古老的API,Google在5.0推出Camera2后就再也没有更新Camera。相比于Camera2来说,Camera API使用非常简单,由于这套框架使用很久了所以稳定性和兼容性还是值得信赖的。另外Camera API只提供基本的功能,其曝光/白平衡/曝光基本无法调节,这是相对于Camera2来说比较弱的地方。

2. Camera使用

有一点需要注意的是:
Camera设备是独占,也就是说你的APP在使用Camera设备的话,其它应用就没法使用。
所以要求在APP切换到后台时需要关闭Camera设备,重入时在重新打开。

2.1 Camera主要类

Camera

Camera可以说是底层相机设备的映射,所有对相机设备的操作都是通过Camera这个类完成。
常用方法:

  • open
    打开相机设备,并返回一个Camera对象。
  • getParameters
    获取Camera.Parameters
  • setParameters
    设置Camera.Parameters
  • setPreviewTexture
    设置用于输出的SurfaceTexture
  • startPreview
    开始预览
  • stopPreview
    结束预览
  • release
    释放设备

Camera.Parameters

保存Camera设备支持的数据,允许用户设置响应的参数(主要是图像大小、格式、预览FPS等)。

2.2 Camera 操作流程

2.2.1 获取Camera权限

  1. APP Manifest 声明
  1. 代码中权限检查
/** Check if this device has a camera */private boolean checkCameraHardware(Context context) {    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){        // this device has a camera        return true;    } else {        // no camera on this device        return false;    }}

2.2.2 打开Camera

打开Camera比较简单,需要注意两件事:

  • 可以选择要打开的是前置还是后置相机,用CameraFacing标识:
        public static final int CAMERA_FACING_BACK = 0;        public static final int CAMERA_FACING_FRONT = 1;
  • 在打开Camera之前需要检查是否已经打开
        try {            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) {                int numberOfCameras = Camera.getNumberOfCameras();                Camera.CameraInfo cameraInfo = new Camera.CameraInfo();                for (int i = 0; i < numberOfCameras; i++) {                    Camera.getCameraInfo(i, cameraInfo);                    if (cameraInfo.facing == facing) {                        mDefaultCameraID = i;                        mFacing = facing;                    }                }            }            stopPreview();            if (mCameraDevice != null)                mCameraDevice.release();            if (mDefaultCameraID >= 0) {                mCameraDevice = Camera.open(mDefaultCameraID);            } else {                mCameraDevice = Camera.open();                mFacing = Camera.CameraInfo.CAMERA_FACING_BACK; //default: back facing            }            mRotation = setOrientationDegrees(0);            TELogUtil.d(TAG, "Camera rotation = " + mRotation);        } catch (Exception e) {            TELogUtil.e(TAG, "Open Camera Failed!");            e.printStackTrace();            mCameraDevice = null;            return false;        }

2.2.3 配置Camera

Camera打开后可以配置 Camera.Parameters:
以设置图像大小的操作顺序为例:

  1. 获取Camera.Parameters
param = camera.getParameters();
  1. 查询设备支持情况
List prevSizes = params.getSupportedPreviewSizes();
  1. 修改Camera.Parameters
prevSize = getBestMatchSize(prevSizes, desireSize);params.setPreviewSize(prevSize.width, prevSize.height);
  1. 把Camera.Parameters设置给Camera
camera.setParameters(params);

常用的配置项:

        //图像格式        mParams.setPictureFormat(ImageFormat.NV21);        //图像分辨率        mParams.setPreviewSize(prevSz.width, prevSz.height);        //预览帧率        mParams.setPreviewFrameRate(30);        //对焦方式        if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {            mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);        }

2.2.4 开始预览

Camera的输出支持多种方式:

  • SurfaceTexture:以纹理的形式输出
    设置Camera.setPreviewTexture(surfaceTexture)
    通过SurfaceTexture的onFrameAvailable回调输出每一帧
  • Buffer:以Buffer形式输出
    通过Camera.setPreviewCallbackWithBuffer(buffer)接口输出
  • Surface:输出到Surface
    通过设置Camera.setPreviewDisplay(surfaceHolder);

下面是SurfaceTexture输出代码示例:

    public synchronized void startPreview(SurfaceTexture texture) {        TELogUtil.i(TAG, "Camera startPreview...");        if (mIsPreviewing) {            TELogUtil.w(TAG, "Camera is previewing...");//            stopPreview();            return;        }        if (mCameraDevice != null) {            try {                mCameraDevice.setPreviewTexture(texture);                mCameraDevice.startPreview();                mIsPreviewing = true;            } catch (Exception e) {                e.printStackTrace();                TELogUtil.e(TAG, "startPreview: Error " + e.getMessage());                mIsPreviewing = false;                try {                    mCameraDevice.release();                } catch (Exception e2) {                    e2.printStackTrace();                }                mCameraDevice = null;            }        }    }

2.2.5 关闭Camera

mCameraDevice.stopPreview();mCameraDevice.close()

更多相关文章

  1. Android调用系统相机拍照并保存,解决OOM
  2. Android(安卓)获取唯一机器码的代码
  3. Android如何调用系统相机拍照
  4. Mac中用命令行启动AVD模拟器
  5. Android之照相机的使用
  6. android 7.0 手机调用手机相机、相册常见的两个崩溃:FileUriExpos
  7. Android(安卓)HIDL lshal
  8. 解决onConfigurationChanged不被调用
  9. Android(安卓)Gallery组件详解

随机推荐

  1. OpenGL ES 纹理过滤模式-glTexParameteri
  2. APP开发实战114-Android Studio打包介绍
  3. Android欢迎界面动画与跳转
  4. Android animation-list动画
  5. smack 源码分析- PacketWriter (android
  6. APP横竖屏不切换,不重走生命周期
  7. android相关技术文档汇总
  8. android隐藏IME(输入法)输入框
  9. android 延时 不用另起线程或timertask
  10. Android用户界面开发(11):Menu