当前位置:   article > 正文

Camera2 和CameraX 从入门到精通 java实现_android camx和camera2

android camx和camera2

此文章我会用Camera2 和CameraX 分别实现预览拍照录制视频

目录

此文章我会用Camera2 和CameraX 分别实现预览拍照录制视频

Camera2

APP实现 Camera2 需要提前声明

相机方向

Camera层级架构

API2流程

废话不多说 实战开始

CameraX

CameraX api

CameraX demo


Camera2

APP实现 Camera2 需要提前声明

相机方向

相机相对于手机屏幕默认方向不一致:

        前置摄像头(指向与显示屏方向相同的摄像头)的传感器相对于手机旋转 270 度(顺时针),以符合 Android 兼容性定义

手机的传感器是顺时针旋转的 左横屏就是90度 

 手机的传感器是顺时针旋转的 右横屏就是270度或者-90度 

Camera层级架构

Camera 只是Android的一部分  所以框架层级整体跟Android一样为

Applications 应用层            -----------------------------对应camera APP

Framework层                      -----------------------------对应Java Framework

Libraries 系统运行库层       -----------------------------对应Native Framework (CameraService)

Hardwre Abstraction layer HAL硬件抽象层-----------------------------对应Camera Provider

Linux Kernel 内核层           -----------------------------对应Camera Driver

Camera根据Android 架构从上至下可分为

    1)Applications: 最上层的应用,编译后生成Camera  APK

    2)Application Framework: 主要为Applications提供API;

    3)JNI: 使Application FrameworkLibraries可交互;

    4)Libraries: 包括Camera FrameworkCamera Service(camera servicecamera client);

    5)HAL: 硬件抽象层用来链接driver Camera Service;

    6)Kernel: image sensor driver的实作.

API2流程

 解释下来 其实就是CameraManager调用openCamera 下发open指令到底层,然后在CameraDevice.StateCallbackonOpened 中 拿到底层返回来的CameraDevice 通过CameraDevice去创建Session(createCaptureSession) 创建Session是需要添加对应的surface 预览的surface 有TextureView SurfaceView 拍照对应的Surface 为ImageReader 然后在Session的状态回调的onConfigured里(CameraCaptureSession.StateCallback)拿到CameraCaptureSession对象  通过CameraCaptureSession 可以申请预览 setRepeatingRequest 或者是 拍照 Capture 录制视频 需要配置 MediaRecorder 

废话不多说 实战开始

首先利用AndroidStudio 创建工程

 

Next

 Finish

打开布局文件

 一步步实现 就慢慢来,activity_main.xml布局文件代码

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="#000000"
  6. >
  7. <TextureView
  8. android:id="@+id/previewSurfaceView"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent" />
  11. <ImageButton
  12. android:id="@+id/takePictureButton"
  13. android:layout_width="wrap_content"
  14. android:layout_height="wrap_content"
  15. android:layout_alignParentBottom="true"
  16. android:layout_centerHorizontal="true"
  17. android:layout_marginBottom="70dp"
  18. android:background="@drawable/shape_white_ring"
  19. android:src="@drawable/shape_take_photo" />
  20. </RelativeLayout>

看到我放了两个控件一个TextureView 用来预览的控件 SurfaceView 等等也可以 还有一个拍照按钮 ImageButton  

首先我们实现预览 预览是一切的基础

  1. package com.example.camera2demo;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import android.os.Bundle;
  4. import android.util.Log;
  5. import android.view.TextureView;
  6. import android.view.View;
  7. import android.widget.ImageButton;
  8. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  9. //预览画面控件
  10. private TextureView mTextureView;
  11. //拍照按钮
  12. private ImageButton mTakePictureButton;
  13. //日志的tag
  14. private final String TAG = "Camera2Demo" ;
  15. @Override
  16. protected void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.activity_main);
  19. //初始化预览控件
  20. mTextureView = findViewById(R.id.previewSurfaceView);
  21. //初始化拍照按钮
  22. mTakePictureButton = findViewById(R.id.takePictureButton);
  23. }
  24. @Override
  25. protected void onStart() {
  26. super.onStart();
  27. //设置拍照按钮监听
  28. mTakePictureButton.setOnClickListener(this);
  29. }
  30. @Override
  31. public void onClick(View v) {
  32. switch (v.getId()){
  33. case R.id.takePictureButton:
  34. takePicture();
  35. break;
  36. }
  37. }
  38. private void takePicture() {
  39. Log.d(TAG,"-----takePicture");
  40. }
  41. }

可以看到 就是在onCreate 里去 初始化 预览控件和拍照按钮 并在 onStart 里去设置按钮 监听

在点击时间里 写了空函数 takePicture 基本框架已经实现 

要实现预览 我们是需要 申请Camera权限的 所以接下来我们先申请权限

Android 6.0 之前只需要在 AndroidManifest.xml 中加入 就OK  6.0 之后需要加入并且动态申请权限

<uses-permission android:name="android.permission.CAMERA" />

 代码 块如下

  1. package com.example.camera2demo;
  2. import androidx.annotation.NonNull;
  3. import androidx.appcompat.app.AppCompatActivity;
  4. import androidx.core.app.ActivityCompat;
  5. import androidx.core.content.ContextCompat;
  6. import android.content.pm.PackageManager;
  7. import android.os.Bundle;
  8. import android.util.Log;
  9. import android.view.TextureView;
  10. import android.view.View;
  11. import android.widget.ImageButton;
  12. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  13. //预览画面控件
  14. private TextureView mTextureView;
  15. //拍照按钮
  16. private ImageButton mTakePictureButton;
  17. //日志的tag
  18. private final String TAG = "Camera2Demo";
  19. //权限字符串数组 因为还需要其他 便于添加权限 选择字符串数组的形式
  20. private final String[] REQUIRED_PERMISSIONS = new String[]{
  21. "android.permission.CAMERA",
  22. };
  23. @Override
  24. protected void onCreate(Bundle savedInstanceState) {
  25. super.onCreate(savedInstanceState);
  26. setContentView(R.layout.activity_main);
  27. //初始化预览控件
  28. mTextureView = findViewById(R.id.previewSurfaceView);
  29. //初始化拍照按钮
  30. mTakePictureButton = findViewById(R.id.takePictureButton);
  31. }
  32. @Override
  33. protected void onResume() {
  34. super.onResume();
  35. //检查权限申请权限
  36. if (allPermissionsGranted()) {
  37. Log.d(TAG, "权限已授予");
  38. } else {
  39. Log.d(TAG, "申请权限");
  40. ActivityCompat.requestPermissions(MainActivity.this, REQUIRED_PERMISSIONS, 1);
  41. }
  42. }
  43. @Override
  44. protected void onStart() {
  45. super.onStart();
  46. //设置拍照按钮监听
  47. mTakePictureButton.setOnClickListener(this);
  48. }
  49. @Override
  50. public void onClick(View v) {
  51. switch (v.getId()){
  52. case R.id.takePictureButton:
  53. takePicture();
  54. break;
  55. }
  56. }
  57. private boolean allPermissionsGranted() {
  58. Log.d(TAG, "----- 检查权限");
  59. for (String permission : REQUIRED_PERMISSIONS) {
  60. if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
  61. return false;
  62. }
  63. }
  64. return true;
  65. }
  66. //权限回调 申请完权限之后 返回的结果在这里接收
  67. @Override
  68. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  69. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  70. //这个1 是申请权限时的第三个参数
  71. if (requestCode == 1) {
  72. if (allPermissionsGranted()) {
  73. openCamera();
  74. } else {
  75. ActivityCompat.requestPermissions(MainActivity.this, REQUIRED_PERMISSIONS, 1);
  76. }
  77. }
  78. }
  79. private void openCamera() {
  80. Log.d(TAG,"----------openCamera");
  81. }
  82. private void takePicture() {
  83. Log.d(TAG,"-----takePicture");
  84. }
  85. }

在刚刚 的基础之上加了三个函数 一个检查权限的函数 一个权限回调函数 一个 openCamera的空函数 权限获取之后我们就正式进入openCamera

  1. package com.example.camera2demo;
  2. import static java.lang.String.valueOf;
  3. import androidx.annotation.NonNull;
  4. import androidx.appcompat.app.AppCompatActivity;
  5. import androidx.core.app.ActivityCompat;
  6. import androidx.core.content.ContextCompat;
  7. import android.annotation.SuppressLint;
  8. import android.content.pm.PackageManager;
  9. import android.graphics.ImageFormat;
  10. import android.hardware.camera2.CameraAccessException;
  11. import android.hardware.camera2.CameraCharacteristics;
  12. import android.hardware.camera2.CameraDevice;
  13. import android.hardware.camera2.CameraManager;
  14. import android.hardware.camera2.params.StreamConfigurationMap;
  15. import android.os.Bundle;
  16. import android.os.Handler;
  17. import android.os.HandlerThread;
  18. import android.util.Log;
  19. import android.util.Size;
  20. import android.view.TextureView;
  21. import android.view.View;
  22. import android.widget.ImageButton;
  23. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  24. //预览画面控件
  25. private TextureView mTextureView;
  26. //拍照按钮
  27. private ImageButton mTakePictureButton;
  28. //日志的tag
  29. private final String TAG = "Camera2Demo";
  30. //权限字符串数组 因为还需要其他 便于添加权限 选择字符串数组的形式
  31. private final String[] REQUIRED_PERMISSIONS = new String[]{
  32. "android.permission.CAMERA",
  33. };
  34. //处理回调函数的线程
  35. private HandlerThread mCameraThread;
  36. private Handler mCameraHandler;
  37. //具体的相机设备
  38. private CameraDevice mCameraDevice;
  39. @Override
  40. protected void onCreate(Bundle savedInstanceState) {
  41. super.onCreate(savedInst
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/102869
推荐阅读
相关标签
  

闽ICP备14008679号