Android --Camera1

2,591 阅读21分钟

camera1

简介

Camera 类用于设置 图像捕获设置、开始/停止预览、拍照以及取出帧用于视频编码。此类是 Camera 服务的客户端,它管理实际的相机硬件。 要访问摄像头需要在清单文件中声明权限 例如,使用相机和自动对焦功能,在清单文件中添加

<manifest ... >
         <uses-permission android:name="android.permission.CAMERA" />
         <uses-feature android:name="android.hardware.camera" />
         <uses-feature android:name="android.hardware.camera.autofocus" />
        ...
</manifest>

官方demo(kotlin)

github.com/android/cam…

官方demo(java)

github.com/google/came…

工具类

github.com/tangdanyu/T…

容易弄混的地方

相机预览尺寸和屏幕尺寸

  • 屏幕尺寸:(1080,2160)width < height
// 获取当前的屏幕尺寸, 放到一个点对象里
Point screenSize = new Point();
((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(screenSize);
  • 相机预览、图片、录像尺寸:(1920,1080) width > height 原因是安卓中相机默认是横屏的,顺时针旋转了90度。

预览方向和图片方向

  • 获得屏幕方向:竖屏下屏幕方向为 0
((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
  • 获得相机方向:前置为270,后置为90
mCameraInfo.orientation
  • 设置预览方向:前置的时候预览方向需要顺时针旋转90,后置的时候预览方向需要顺时针旋转90,
mCamera.setDisplayOrientation
  • 设置图片方向:图片的方向与相机传感器有关,不设置的话拍出的照片和预览不一致
mCameraParameters.setRotation

自定义相机界面步骤

  1. 检测和访问相机  - 创建代码以检查设备是否配有相机并请求访问权限。
  2. 创建预览类  - 创建一个扩展 SurfaceView 并实现 SurfaceHolder 接口的相机预览类。此类预览来自摄像机的实时图像。
  3. 构建预览布局  - 拥有相机预览类后,创建一个融合预览和您想要的界面控件的视图布局。
  4. 为捕获设置侦听器 - 为界面控件连接侦听器,以便启用图像或视频捕获来响应用户操作,例如按下按钮。
  5. 捕获并保存文件  - 创建用于捕获图片或视频并保存输出的代码。
  6. 释放相机 - 在用完相机之后,您的应用必须正确地释放相机,以便其他应用使用。

拍照步骤

  1. 获取摄影机的实例,通过 open(int)
  2. 获得现有(默认)设置,通过getParameters()
  3. 如果需要修改参数设置,修改2.中返回的Camera.Parameters对象,调用setParameters(android.hardware.Camera.Parameters)
  4. 设置正确的预览方向,调用setDisplayOrientation(int)
  5. 设置预览控件,调用setPreviewDisplay(android.view.SurfaceHolder) 注意:要传递一个完全初始化SurfaceHolder,否则相机无法开始预览
  6. 开始预览,调用startPreview() 注意:必须先开始预览,然后才能拍照
  7. 如果需要拍照,调用takePicture(android.hardware.Camera.ShutterCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback),等待回调返回实际图像数据
  8. 拍照后预览将会停止,如果需要再次拍照,需要重新开始预览,调用startPreview()
  9. 停止预览,调用stopPreview()
  10. 释放相机,调用release() 注意:应用应该在Activity.onPause() 中调用release(),在Activity.onResume()open(int)

录制步骤

  1. 获取摄影机的实例,通过 open(int)
  2. 获得现有(默认)设置,通过getParameters()
  3. 如果需要修改参数设置,修改2.中返回的Camera.Parameters对象,调用setParameters(android.hardware.Camera.Parameters)
  4. 设置正确的预览方向,调用setDisplayOrientation(int)
  5. 设置预览控件,调用setPreviewDisplay(android.view.SurfaceHolder) 注意:要传递一个完全初始化SurfaceHolder,否则相机无法开始预览
  6. 开始预览,调用startPreview() 注意:必须先开始预览,然后才能录制
  7. 允许媒体进程访问相机,调用unlock()
  8. 将相机传递给MediaRecorder.setCamera(Camera)
  9. 录制完成后,重新获取并重新锁定摄像机,调用reconnect()
  10. 如果需要再次录制或拍照,需要重新开始预览,调用startPreview()
  11. 停止预览,调用stopPreview()
  12. 释放相机,调用release() 注意:应用应该在Activity.onPause() 中调用release(),在Activity.onResume()open(int)

公共方法

自动对焦

public final void autoFocus (Camera.AutoFocusCallback cb)

启动相机自动对焦并注册一个回调函数以在相机对焦时运行。此方法仅在预览处于活动状态(介于startPreview()和之前stopPreview())时有效。
通过Camera.Parameters.getFocusMode()应检查以确定是否应调用此方法。如果相机不支持自动对焦,则为空操作,AutoFocusCallback#onAutoFocus(boolean, Camera) 将立即被调用。
如果您的应用程序不应安装在没有自动对焦的设备上,在清单文件中添加 <uses-feature android:name="android.hardware.camera.autofocus" />声明您的应用程序使用自动对焦。
如果当前的闪光灯模式不是 Camera.Parameters.FLASH_MODE_OFF,则在自动对焦期间可能会闪光,具体取决于驱动程序和相机硬件。
自动曝光锁定Camera.Parameters.getAutoExposureLock() 和自动白平衡锁定Camera.Parameters.getAutoWhiteBalanceLock() 在自动对焦期间和之后不会改变。但是自动对焦程序可能会在对焦过程中暂时停止自动曝光和自动白平衡。
停止预览stopPreview(),或触发拍照takePicture(android.hardware.Camera.ShutterCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback),不会改变焦点位置。应用程序必须调用 cancelAutoFocus 来重置焦点。
如果自动对焦成功,请考虑使用 MediaActionSound向用户正确播放自动对焦成功的声音。

取消自动对焦

public final void cancelAutoFocus ()

取消任何正在进行的自动对焦功能。无论当前是否正在进行自动对焦,此功能都会将焦点位置恢复为默认值。如果相机不支持自动对焦,则无操作。

启用快门声

public final boolean enableShutterSound (boolean enabled)

拍照时启用或禁用默认快门声音。
默认情况下,相机在takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback)调用时播放系统定义的相机快门声音。使用此方法,可以禁用快门声音。 强烈建议在禁用系统快门声音时,在ShutterCallback中播放备用快门声音。
请注意,设备可能并不总是允许禁用相机快门声音。如果无法将快门声音状态设置为所需值,则此方法CameraInfo#canDisableShutterSound将返回 false。调用这个方法可用于确定设备是否允许禁用快门声音。

获取相机信息

public static void getCameraInfo (int cameraId, Camera.CameraInfo cameraInfo)

返回有关特定相机的信息

获取相机数量

public static int getNumberOfCameras ()

返回此设备上可用的物理摄像头数量。如果设备支持外部摄像头并且连接或断开外部摄像头,则此方法的返回值可能会动态变化。

获取参数

public Camera.Parameters getParameters ()

返回此相机服务的当前设置

public final void lock ()

重新锁定相机以防止其他进程访问它。除非unlock()调用,否则默认情况下会锁定相机对象。通常使用reconnect()代替。
API14之后,应用程序在调用MediaRecorder.start()会自动锁定摄像头,可以在录制开始之后使用相机(例如缩放),录制开始或者停止后无需调用lock()
如果不录制视频,则可能不需要此方法\

开锁

public final void unlock ()

解锁相机以允许另一个进程访问它。通常,相机被锁定到具有活动相机对象的进程,直到release()被调用。为了允许进程间快速切换,可以调用该方法暂时释放摄像头供其他进程使用;其他过程完成后,您可以调用reconnect()回收相机。
这必须在调用MediaRecorder.setCamera(Camera)之前完成 。录制开始后无法调用。
如果您不录制视频,则可能不需要此方法。\

重新连接

public final void reconnect ()

在另一个进程使用它后重新连接到相机服务。之后unlock()被调用时,另一过程可使用相机; 该过程完成后,您必须重新连接到相机,这将重新获取锁定并允许您继续使用相机。
从 API 级别 14 开始,相机会自动锁定 MediaRecorder.start(). 应用程序可以在录制开始后使用相机(例如:变焦)。录制开始或停止后无需调用此方法。
如果您不录制视频,则可能不需要此方法。\

打开

public static Camera open ()

创建一个新的 Camera 对象以访问设备上的第一个后置摄像头。如果设备没有后置摄像头,则返回 null。

public static Camera open (int cameraId)

创建一个新的 Camera 对象以访问特定的硬件相机。如果其他应用程序打开了同一个相机,这将抛出一个 RuntimeException。
您必须在使用完相机后调用release(),否则它将保持锁定状态,其他应用程序无法使用。 对于特定的硬件相机,您的应用程序一次应该只有一个处于活动状态的 Camera 对象。
来自其他方法的回调被传递到调用 open() 的线程的事件循环。如果此线程没有事件循环,则回调将传递到主应用程序事件循环。如果没有主应用程序事件循环,则不会传递回调。
** 注意:** 在某些设备上,此方法可能需要很长时间才能完成。最好从工作线程(可能使用AsyncTask)调用此方法以避免阻塞主应用程序 UI 线程。\

释放

public final void release ()

断开并释放相机对象资源。
完成 Camera 对象后,您必须立即调用它。

设置显示方向

public final void setDisplayOrientation (int degrees)

以度为单位设置预览显示的顺时针旋转。这会影响预览帧和快照后显示的图片。此方法对于纵向模式应用程序很有用。注意前置摄像头的预览显示在旋转前是水平翻转的,即图像沿摄像头传感器的中心垂直轴反射。所以用户可以看到自己在照镜子。
这不会影响传入的字节数组的顺序Camera.PreviewCallback.onPreviewFrame(byte[], Camera)、JPEG 图片或录制的视频。预览时不允许调用此方法。
如果要使相机图像以与显示器相同的方向显示,可以使用以下代码。\

 public static void setCameraDisplayOrientation(Activity activity,
         int cameraId, android.hardware.Camera camera) {
     android.hardware.Camera.CameraInfo info =
             new android.hardware.Camera.CameraInfo();
     android.hardware.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);
 }
 

从 API 级别 14 开始,可以在预览处于活动状态时调用此方法。
注意: 在 API 级别 24 之前,方向的默认值为 0。从 API 级别 24 开始,默认方向将是强制横向模式下的应用程序将具有正确的预览方向,默认值可能是 0 或 180 . 以纵向模式运行或允许更改方向的应用程序仍必须在每次更改方向后调用此方法,以确保在所有情况下都能正确显示预览。\

设置错误回调

public final void setErrorCallback (Camera.ErrorCallback cb)

注册一个回调以在发生错误时调用。

设置人脸检测监听器

public final void setFaceDetectionListener (Camera.FaceDetectionListener listener)

注册一个侦听器,以接收有关在预览帧中检测到的人脸的通知。

开始人脸检测

public final void startFaceDetection ()

开始人脸检测。这应该在预览开始后调用。相机将FaceDetectionListener在预览帧中通知检测到的人脸。检测到的人脸可能与之前的人脸相同。应用程序应调用stopFaceDetection()停止人脸检测。如果Camera.Parameters.getMaxNumDetectedFaces()返回大于 0 的数字,则支持此方法。如果人脸检测已启动,应用程序不应再次调用此方法。
人脸检测运行时,Parameters#setWhiteBalance(String)、 Parameters#setFocusAreas(List)、 和Parameters#setMeteringAreas(List) 无效。相机使用检测到的人脸进行自动白平衡、自动曝光和自动对焦。
如果应用调用autoFocus(android.hardware.Camera.AutoFocusCallback),相机将停止发送人脸回调。最后一个人脸回调指示用于进行自动对焦的区域。焦点完成后,人脸检测将继续发送人脸回调。如果应用调用cancelAutoFocus(),人脸回调也将恢复。
调用takePicture(android.hardware.Camera.ShutterCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback)或 后stopPreview(),然后使用 恢复预览startPreview(),应用程序应再次调用此方法以恢复人脸检测。

停止人脸检测

public final void stopFaceDetection ()

停止人脸检测。

设置参数

public void setParameters (Camera.Parameters params)

更改此相机服务的设置。

添加回调缓冲区

public final void addCallbackBuffer (byte[] callbackBuffer)

添加预先分配好的缓冲区到预览回调缓冲区队列,可以添加一个或者多个缓冲区到预览队列。 当一个视频帧到达并且有一个可用的缓冲区,这个缓冲区将被使用并从队列中移除,然后使用缓冲区调用预览回调。
当一个视频帧到达并且没有剩余缓冲区,则丢弃该帧。
应用程序在处理完其中的数据后应重新添加缓冲区。
非YV12缓冲区大小:由预览图像的宽高和每像素字节数相乘,宽高Camera.Parameters#getPreviewSize() ,每像素字节数ImageFormat.getBitsPerPixel(int)/ 8,视频帧的格式为Camera.Parameters#getPreviewFormat() YV12格式缓冲区大小:预览尺寸为width x height,公式为:\

 yStride   = (int) ceil(width / 16.0) * 16;
 uvStride  = (int) ceil( (yStride / 2) / 16.0) * 16;
 ySize     = yStride * height;
 uvSize    = uvStride * height / 2;
 yRowIndex = yStride * y;
 uRowIndex = ySize + uvSize + uvStride * c;
 vRowIndex = ySize + uvStride * c;
 size      = ySize + uvSize * 2;

addCallbackBuffer只有使用setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback)时才调用,当提供的缓冲区太小而无法容纳预览帧数据时,预览回调将返回 null 并且缓冲区将从缓冲区队列中删除。
setPreviewCallback(android.hardware.Camera.PreviewCallback)或  setOneShotPreviewCallback(android.hardware.Camera.PreviewCallback),会自动分配缓冲区。

设置预览回调

public final void setPreviewCallback (Camera.PreviewCallback cb)

除了在屏幕上显示它们之外,安装要为每个预览帧调用的回调。只要预览处于活动状态,就会重复调用回调。可以随时调用此方法,即使在预览处于实时状态时也是如此。任何其他预览回调都会被覆盖。
如果您使用预览数据来创建视频或静止图像,请强烈考虑使用MediaActionSound以向用户正确指示图像捕获或录制开始/停止。\

public final void setPreviewCallbackWithBuffer (Camera.PreviewCallback cb)

addCallbackBuffer(byte[])除了在屏幕上显示它们之外,还使用随 提供的缓冲区安装要为每个预览帧调用的回调。只要预览处于活动状态并且缓冲区可用,就会重复调用回调。任何其他预览回调都会被覆盖。
这种方法的目的是通过允许预览帧内存重用来提高预览效率和帧率。您必须 addCallbackBuffer(byte[])在某个时刻调用——在调用此方法之前或之后——否则将不会收到回调。
如果使用空回调调用、setPreviewCallback(android.hardware.Camera.PreviewCallback)调用或setOneShotPreviewCallback(android.hardware.Camera.PreviewCallback)调用此方法,则缓冲区队列将被清除。
如果您使用预览数据来创建视频或静止图像,请强烈考虑使用MediaActionSound以向用户正确指示图像捕获或录制开始/停止。\

设置预览显示

public final void setPreviewDisplay (SurfaceHolder holder)

设置Surface用于实时预览的 。预览需要表面或表面纹理,并且需要预览才能拍照。可以重新设置相同的表面而不会造成伤害。设置预览表面将取消设置通过setPreviewTexture(SurfaceTexture).
SurfaceHolder调用此方法时,必须已经包含一个表面。如果你正在使用SurfaceView,你需要注册一个SurfaceHolder.Callback与 SurfaceHolder#addCallback(SurfaceHolder.Callback)等待 SurfaceHolder.Callback#surfaceCreated(SurfaceHolder)调用setPreviewDisplay()或启动前预览。
此方法必须在 之前调用startPreview()。一个例外是,如果在调用 startPreview() 之前未设置(或设置为空)预览表面,则可以使用非空参数调用此方法一次以设置预览表面。(这允许相机设置和表面创建并行进行,从而节省时间。)预览表面在预览运行时可能不会以其他方式更改。\

设置预览纹理

public final void setPreviewTexture (SurfaceTexture surfaceTexture)

设置SurfaceTexture用于实时预览的 。预览需要表面或表面纹理,并且需要预览才能拍照。可以重新设置相同的表面纹理而不会造成伤害。设置预览表面纹理将取消设置通过setPreviewDisplay(SurfaceHolder).
此方法必须在 之前调用startPreview()。一个例外是,如果在调用 startPreview() 之前未设置(或设置为 null)预览表面纹理,则可以使用非空参数调用此方法一次以设置预览表面。(这允许相机设置和表面创建并行发生,从而节省时间。)预览表面纹理在预览运行时可能不会改变。
SurfaceTexture#getTimestamp()设置为预览纹理的 SurfaceTexture提供的时间戳具有未指定的零点,并且无法在不同相机或同一相机的不同实例之间直接比较,或在同一程序的多次运行之间进行比较。
如果您使用预览数据来创建视频或静止图像,请强烈考虑使用MediaActionSound以向用户正确指示图像捕获或录制开始/停止。\

开始预览

public final void startPreview ()

开始捕获预览帧并将其绘制到屏幕上。直到表面提供setPreviewDisplay(android.view.SurfaceHolder)或 时, 预览才会真正开始setPreviewTexture(android.graphics.SurfaceTexture)
如果setPreviewCallback(android.hardware.Camera.PreviewCallback)、 setOneShotPreviewCallback(android.hardware.Camera.PreviewCallback)或被 setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback)调用,Camera.PreviewCallback#onPreviewFrame(byte[], Camera) 将在预览数据可用时调用。

停止预览

public final void stopPreview ()

停止捕获和绘制预览帧到表面,并重置相机以备将来调用startPreview()

开始平滑缩放

public final void startSmoothZoom (int value)

平滑地缩放到请求的值。驱动程序会通知OnZoomChangeListener缩放值以及此时是否停止缩放。例如,假设当前缩放为 0 并且 startSmoothZoom 以值为 3 调用。该 Camera.OnZoomChangeListener#onZoomChange(int, boolean, Camera) 方法将使用缩放值为 1、2 和 3 调用三次。应用程序可以调用stopSmoothZoom()以提前停止缩放。应用程序不应在缩放停止之前再次调用 startSmoothZoom 或更改缩放值。如果提供的缩放值等于当前缩放值,则不会生成缩放回调。如果调用Camera.Parameters.isSmoothZoomSupported() 返回 true,则支持平滑缩放。

停止平滑缩放

public final void stopSmoothZoom ()

停止平滑缩放。应用程序应等待OnZoomChangeListener知道缩放何时实际停止。如果Camera.Parameters.isSmoothZoomSupported()为 true,则支持此方法。

拍照片

public final void takePicture (Camera.ShutterCallback shutter, 
                Camera.PictureCallback raw, 
                Camera.PictureCallback postview, 
                Camera.PictureCallback jpeg)

触发异步图像捕获。随着图像捕获的进行,相机服务将启动对应用程序的一系列回调。拍摄图像后发生快门回调。这可用于触发声音,让用户知道图像已被捕获。当原始图像数据可用时发生原始回调(注意:如果没有可用的原始图像回调缓冲区或原始图像回调缓冲区不足以容纳原始图像,则数据将为空)。当缩放的、完全处理的 postview 图像可用时,postview 回调发生(注意:并非所有硬件都支持这一点)。当压缩图像可用时,会发生 jpeg 回调。如果应用程序不需要特定的回调,则可以传递 null 而不是回调方法。

此方法仅在预览处于活动状态时(之后 startPreview())有效。拍摄图像后将停止预览;startPreview()如果呼叫者想重新开始预览或拍摄更多照片,则必须再次呼叫。这不应在MediaRecorder.start()和 之间调用 MediaRecorder.stop()

调用此方法后,startPreview() 在 JPEG 回调返回之前,您不得调用或拍摄另一张照片。

public final void takePicture (Camera.ShutterCallback shutter, 
                Camera.PictureCallback raw, 
                Camera.PictureCallback jpeg)

相当于

takePicture(Shutter, raw, null, jpeg)

参数设置

相机当前设置

 public void getFlatten() {
        Camera.Parameters parameters = mCamera.getParameters();
        String str = parameters.flatten();
        MyLogUtil.e(TAG, "相机参数 " + str);
    }

切换相机

    //切换相机
 
    public void switchCamera() {
        mFacing = (mCameraId == CameraView.FACING_FRONT) ?
            CameraView.FACING_BACK : CameraView.FACING_FRONT;
        if (isCameraOpened()) {
            stop();
            start();
        }
    }   

传入参数名称设置

    //传入参数名称设置
    public String setParameter(String key, String value, int num) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            if (key.equals("auto-exposure-lock")) {
                if (!getParameterSupport("auto-exposure-lock-supported")) {
                    return "不支持设置自动曝光锁定";
                }
            }
            if (key.equals("auto-whitebalance-lock")) {
                if (!getParameterSupport("auto-whitebalance-lock-supported")) {
                    return "不支持设置自动白平衡锁定";
                }
            }
            if (!TextUtils.isEmpty(value)) {
                parameters.set(key, value);
            } else if (num != -100) {
                parameters.set(key, num);
            }
            try {
                mCamera.setParameters(parameters);
                return "设置成功!";
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
        return "设置失败!";
    }
    

传入参数名称查看是否支持

    //传入参数名称查看是否支持
    public boolean getParameterSupport(String key) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            return parameters.get(key).equals("true");
        }
        return false;
    }

传入参数名称查看值

    public int getParameterValue(String key) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            return Integer.parseInt(parameters.get(key));
        }
        return 0;
    }

设置自动曝光锁定状态

    // 设置自动曝光锁定状态 不要在Camera.open()与Camera.startPreview()之间调用此方法
    public void setAutoExposureLock(boolean toggle) {
        if (!isAutoExposureLockSupported()) {
            return;
        }
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setAutoExposureLock(toggle);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

是否支持自动曝光锁定

    //是否支持自动曝光锁定
    public boolean isAutoExposureLockSupported() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            return parameters.isAutoExposureLockSupported();
        }
        return false;
    }

设置自动白平衡锁定状态

    //设置自动白平衡锁定状态 不要在Camera.open()与Camera.startPreview()之间调用此方法
    public void setAutoWhiteBalanceLock(boolean toggle) {
        if (!isAutoWhiteBalanceLockSupported()) {
            return;
        }
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setAutoWhiteBalanceLock(toggle);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

是否支持自动白平衡锁定

    //是否支持自动白平衡锁定
    public boolean isAutoWhiteBalanceLockSupported() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            return parameters.isAutoWhiteBalanceLockSupported();
        }
        return false;
    }

获取当前的色彩效果设置

    //获取当前的色彩效果设置
    public String getColorEffect() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            return parameters.getColorEffect();
        }
        return null;
    }

设置当前的色彩效果设置

    //设置当前的色彩效果设置
    public void setColorEffect(String value) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setColorEffect(value);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

最小曝光补偿指数

    //最小曝光补偿指数
    public synchronized int getMinExposureCompensation() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            //最小曝光补偿指数
            int minExpoDuration = parameters.getMinExposureCompensation();
            MyLogUtil.e(TAG, "相机参数 最小曝光补偿指数" + minExpoDuration);
            return minExpoDuration;
        }
        return 0;
    }

最大曝光补偿指数

    //最大曝光补偿指数
    public synchronized int getMaxExposureCompensation() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            //最小曝光补偿指数
            int maxExpoDuration = parameters.getMaxExposureCompensation();
            MyLogUtil.e(TAG, "相机参数 最大曝光补偿指数" + maxExpoDuration);
            return maxExpoDuration;
        }
        return 0;
    }

当前曝光补偿指数

    //当前曝光补偿指数
    public synchronized int getExposureCompensation() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            //当前曝光补偿指数
            int expoDuration = parameters.getExposureCompensation();
            MyLogUtil.e(TAG, "相机参数 当前曝光补偿指数" + expoDuration);
            return expoDuration;
        }
        return 0;
    }

设置相机曝光补偿指数

    //设置相机曝光补偿指数 有效值范围是getMinExposureCompensation()(包括)到getMaxExposureCompensation()(包括)//0表示不调整曝光。
    public synchronized int setExposureCompensation(int exposureCompensation) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            //最大曝光补偿指数
            int maxExpoDuration = parameters.getMaxExposureCompensation();
            //最小曝光补偿指数
            int minExpoDuration = parameters.getMinExposureCompensation();
            MyLogUtil.e(TAG, "相机参数 最大曝光补偿指数" + maxExpoDuration);
            MyLogUtil.e(TAG, "相机参数 最小曝光补偿指数" + minExpoDuration);
            double exposureDuration = clampValue(maxExpoDuration, minExpoDuration, exposureCompensation);
            MyLogUtil.e(TAG, "相机参数 设置曝光补偿指数" + minExpoDuration);
            parameters.setExposureCompensation((int) exposureDuration);
            try {
                mCamera.setParameters(parameters);
                return (int) exposureDuration;
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
        return 0;
    }

获取当前的闪光模式设置

    //获取当前的闪光模式设置
    public String getFlashMode() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            //当前曝光补偿指数
            return parameters.getFlashMode();
        }
        return null;
    }

设置闪光模式

    //设置闪光模式
    public synchronized void setFlashMode(String flash) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            switch (flash) {
                case Camera.Parameters.FLASH_MODE_OFF: {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    break;
                }
                case Camera.Parameters.FLASH_MODE_ON: {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
                    break;
                }
                case Camera.Parameters.FLASH_MODE_AUTO: {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                    break;
                }
                case Camera.Parameters.FLASH_MODE_TORCH: {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                    break;
                }
                default:
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    break;
            }
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

获取支持的最大焦点区域数

    //获取支持的最大焦点区域数
    public synchronized int getMaxNumFocusAreas() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            return parameters.getMaxNumFocusAreas();
        }
        return 0;
    }

获取当前的重点领域

    //获取当前的重点领域
    public synchronized List<Camera.Area> getFocusAreas() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            return parameters.getFocusAreas();
        }
        return null;
    }

设置重点领域

    //设置重点领域 如果getMaxNumFocusAreas值为0,则不支持聚焦区域。
    public synchronized void setFocusAreas(List<Camera.Area> focusAreas) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setFocusAreas(focusAreas);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置对焦模式

    //设置对焦模式
    public synchronized void setFocusMode(String focus) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            switch (focus) {
                case Camera.Parameters.FOCUS_MODE_AUTO: {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                    break;
                }
                case Camera.Parameters.FOCUS_MODE_INFINITY: {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
                    break;
                }
                case Camera.Parameters.FOCUS_MODE_MACRO: {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
                    break;
                }
                case Camera.Parameters.FOCUS_MODE_FIXED: {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
                    break;
                }
                case Camera.Parameters.FOCUS_MODE_EDOF: {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_EDOF);
                    break;
                }
                case Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO: {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                    break;
                }
                default:
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                    break;
            }
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

对焦模式

    //对焦模式
    public synchronized List<String> getSupportedFocusModes() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            List<String> getSupportedFocusModes = parameters.getSupportedFocusModes();
            for (int i = 0; i < getSupportedFocusModes.size(); i++) {
                MyLogUtil.e(TAG, "相机参数 支持的对焦模式列表 " + getSupportedFocusModes.get(i));
            }
            return getSupportedFocusModes;
        }
        return null;
    }

setAutoFocusLock

    //调用一次对焦一次
    public void setAutoFocusLock(boolean isLock){
        if (mCamera != null){
            Camera.Parameters parameters = mCamera.getParameters();
            if(isLock){
                if(parameters.getFocusMode().equals(Camera.Parameters.FLASH_MODE_AUTO)){
                    mCamera.autoFocus(new Camera.AutoFocusCallback() {
                        @Override
                        public void onAutoFocus(boolean success, Camera camera) {

                        }
                    });
                }
            }else {
                mCamera.cancelAutoFocus();
                mCamera.autoFocus(null);
            }

        }
    }

设置GPS高度

    //设置GPS高度
    public void setGpsAltitude(double altitude) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setGpsAltitude(altitude);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置GPS纬度坐标

    //设置GPS纬度坐标
    public void setGpsLatitude(double latitude) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setGpsLatitude(latitude);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置GPS经度坐标

    //设置GPS经度坐标
    public void setGpsLongitude(double longitude) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setGpsLongitude(longitude);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置GPS处理方法

    //设置GPS处理方法
    public void setGpsProcessingMethod(String processing_method) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setGpsProcessingMethod(processing_method);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置GPS时间戳

    //设置GPS时间戳
    public void setGpsTimestamp(long timestamp) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setGpsTimestamp(timestamp);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置拍摄图片的Jpeg质量

    //设置拍摄图片的Jpeg质量 范围是1到100,最好是100。
    public void setJpegQuality(int quality) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setJpegQuality(quality);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置Jpeg图片中EXIF缩略图的质量

    //设置Jpeg图片中EXIF缩略图的质量 范围是1到100,最好是100。
    public void setJpegThumbnailQuality(int quality) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setJpegThumbnailQuality(quality);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置Jpeg图片中EXIF缩略图的尺寸

    //设置Jpeg图片中EXIF缩略图的尺寸 如果应用程序将宽度和高度都设置为0,则EXIF将不包含缩略图。
    public void setJpegThumbnailSize(int width, int height) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setJpegThumbnailSize(width, height);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

获取支持的最大测光区域数

    //获取支持的最大测光区域数
    public synchronized int getMaxNumMeteringAreas() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            return parameters.getMaxNumMeteringAreas();
        }
        return 0;
    }

获取当前的测光区域

    //获取当前的测光区域
    public List<Camera.Area> getMeteringAreas() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            return parameters.getMeteringAreas();
        }
        return null;
    }

设置测光区域

    //设置测光区域 如果getMaxNumMeteringAreas值为0,则不支持测光区域。
    public synchronized void setMeteringAreas(List<Camera.Area> meteringAreas) {
        if (getMaxNumMeteringAreas() == 0) {
            return;
        }
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setMeteringAreas(meteringAreas);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置图片的图像格式

    //设置图片的图像格式
    public void setPictureFormat(int pixel_format) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPictureFormat(pixel_format);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置图片的尺寸

    //设置图片的尺寸 参考setPreviewSize(int, int)
    public void setPictureSize(int width, int height) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPictureSize(width, height);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置预览图片的图像格式

    //设置预览图片的图像格式 默认格式为 ImageFormat.NV21
    public void setPreviewFormat(int pixel_format) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewFormat(pixel_format);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置最小和最大预览fps

    //设置最小和最大预览fps
    public synchronized void setPreviewFpsRange(int min, int max) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewFpsRange(min, max);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

获取支持的预览fps(每秒帧数)范围

    //获取支持的预览fps(每秒帧数)范围
    public synchronized List<String> getSupportedPreviewFpsRange() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            List<int[]> getSupportedPreviewFpsRange = parameters.getSupportedPreviewFpsRange();
            List<String> supportedPreviewFpsRange = new ArrayList<>();
            for (int i = 0; i < getSupportedPreviewFpsRange.size(); i++) {
                String range = "";
                for (int j = 0; j < getSupportedPreviewFpsRange.get(i).length; j++) {
                    range = range + getSupportedPreviewFpsRange.get(i)[j] + " ";
                }
                supportedPreviewFpsRange.add(range);
                MyLogUtil.e(TAG, "相机参数 支持的帧率范围列表 " + range);
            }
            return supportedPreviewFpsRange;
        }
        return null;
    }

设置接收预览帧的速率

    //设置接收预览帧的速率。这是目标帧率。实际帧速率取决于驱动程序。
    public synchronized void setPreviewFrameRate(int value) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewFrameRate(value);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

支持的帧率列表

    //支持的帧率列表
    public synchronized List<Integer> getSupportedPreviewFrameRates() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            List<Integer> getSupportedPreviewFrameRates = parameters.getSupportedPreviewFrameRates();
            for (int i = 0; i < getSupportedPreviewFrameRates.size(); i++) {
                MyLogUtil.e(TAG, "相机参数 支持的帧率列表 " + getSupportedPreviewFrameRates.get(i));
            }
            return getSupportedPreviewFrameRates;
        }
        return null;
    }

设置预览图片的尺寸

    //设置预览图片的尺寸
    public void setPreviewSize(int width, int height) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewSize(width, height);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置录制模式

    //设置录制模式
    public synchronized void setRecordingHint(boolean hint) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setRecordingHint(hint);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

设置相对于相机方向的顺时针旋转角度

    //设置相对于相机方向的顺时针旋转角度(以度为单位)
    public void setRotation(int rotation) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setRotation(rotation);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

    public void onOrientationChanged(int orientation) {
        if (orientation == ORIENTATION_UNKNOWN) return;
        Camera.CameraInfo info =
                new Camera.CameraInfo();
        Camera.getCameraInfo(mCameraId, info);
        orientation = (orientation + 45) / 90 * 90;
        int rotation = 0;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            rotation = (info.orientation - orientation + 360) % 360;
        } else {  // back-facing camera
            rotation = (info.orientation + orientation) % 360;
        }
        setRotation(rotation);
    }

设置场景模式

    //设置场景模式
    public synchronized void setSceneMode(String value) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setSceneMode(value);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

支持场景模式列表

    //支持场景模式列表
    public synchronized List<String> getSupportedSceneModes() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            List<String> getSupportedSceneMode = parameters.getSupportedSceneModes();
            for (int i = 0; i < getSupportedSceneMode.size(); i++) {
                MyLogUtil.e(TAG, "相机参数 支持的场景模式列表 " + getSupportedSceneMode.get(i));
            }
            return getSupportedSceneMode;
        }
        return null;
    }

启用和禁用视频稳定

    //启用和禁用视频稳定
    public void setVideoStabilization(boolean toggle) {
        if (!isVideoStabilizationSupported()) {
            return;
        }
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setVideoStabilization(toggle);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }

    }

是否支持视频稳定

    //是否支持视频稳定
    public boolean isVideoStabilizationSupported() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            return parameters.isVideoStabilizationSupported();
        }
        return false;
    }

设置白平衡

    //设置白平衡
    public synchronized void setWhiteBalance(String value) {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setWhiteBalance(value);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

支持的白平衡列表

    //支持的白平衡列表
    public synchronized List<String> getSupportedWhiteBalance() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            List<String> getSupportedWhiteBalance = parameters.getSupportedWhiteBalance();
            for (int i = 0; i < getSupportedWhiteBalance.size(); i++) {
                MyLogUtil.e(TAG, "相机参数 支持的白平衡列表 " + getSupportedWhiteBalance.get(i));
            }
            return getSupportedWhiteBalance;
        }
        return null;
    }

设置当前缩放值

    //设置当前缩放值
    public void setZoom(int value) {
        if (!isZoomSupported()) {
            return;
        }
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setZoom(value);
            try {
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // ignore failures for minor parameters like this for now
            }
        }
    }

是否支持缩放

    //是否支持缩放
    public boolean isZoomSupported() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            return parameters.isZoomSupported();
        }
        return false;
    }