Android study notes---Camera

The API and related knowledge of the camera have been described above, and we will explain the examples of the camera below.

Android uses camera to develop the most basic process of taking pictures:

  • Use open(int cameraId) to get the camera instance.
  • Set the preview class for the camera instance, which is a SurfaceHolder object, set by setPreviewDisplay(SurfaceHolder).
  • Call startPreview() to start the preview of the camera instance
  • Call the takePicture() method to take a picture, and the captured Image data can be obtained through the Camera.PictureCallback() callback.
  • When the shooting is complete, you need to call stopPreview() to stop the preview, and use release() to release the resources occupied by the camera.

The above steps are an essential process. The camera has no public constructor, and the camera instance can only be obtained through the open() method, and a surfaceHolder preview class is set. If this step is not implemented, the camera will not be able to be used. After the camera is used, release() must be used to release the camera resource. The following examples are explained in detail.

The following example is broken down into these steps:

  • System permission configuration
  • camera layout
  • Camera Preview Settings
  • camera to take pictures

System permission configuration

// 相机权限
<uses-permission android:name="android.permission.CAMERA" />
// 文件读写权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
// 相机自动对焦配置
<uses-feature android:name="android.hardware.camera.autofocus" />

camera layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MyCameraActivity">
​
    <!--预览相机画面-->
    <SurfaceView
        android:id="@+id/surface_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
​    
    <!--两个按钮,取消和拍照-->
    <LinearLayout
        android:id="@+id/view_bottom_operate"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:background="#FFF"
        android:gravity="center"
        android:orientation="horizontal"
        android:paddingStart="10dp"
        android:paddingEnd="10dp"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">
​
        <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/btn_cancle"
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="取消"
            android:textColor="#000"
            android:src="@mipmap/icon_cancle"
            android:textSize="18sp" />
​
        <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/btn_take_picture"
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="点击拍照"
            android:textColor="#000"
            android:src="@mipmap/icon_take_picture"
            android:textSize="18sp" />
​
        <androidx.appcompat.widget.AppCompatImageView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text=""
            android:textColor="#000"
            android:textSize="18sp" />
    </LinearLayout>
​
</androidx.constraintlayout.widget.ConstraintLayout>
 

Camera Preview Settings

The camera preview setting needs to obtain the camera and the camera preview size first, and then display the camera preview screen through SurfaceView .

get a camera

/**
* 获取相机实例
* 
* @param cameraId 相机编号
* @param degrees 预览旋转角度
* @return
*/
private Camera getCamera(int cameraId, int degrees) {
    if (null == mCamera) {
        try {
            mCamera = Camera.open(cameraId);
            mCamera.setDisplayOrientation(degrees);
        } catch (Exception e) {
            
        }
    }
    return mCamera;
}
 

Get the best preview size

1. Obtain all preview resolutions supported by the camera

// 获取相机支持的所有预览分辨率
 List<Camera.Size> allSupportedSize = 
            mCamera.getParameters().getSupportedPreviewSizes();

2. Calculate the appropriate resolution for preview

This step is to obtain a maximum resolution size with the same resolution ratio as SurfaceView, so that the photo will not be deformed when previewing and taking pictures.

    /**
     * 获取适合的分辨率
     *
     * @param camera camera实例
     * @param rate 预览尺寸长宽比
     * @return 获取
     */
    private Camera.Size getSupportedPreviewSize(Camera camera, int rate) {
        Camera.Parameters camPara = camera.getParameters();
        List<Camera.Size> allSupportedSize = camPara.getSupportedPreviewSizes();
        for (Camera.Size tmpSize : allSupportedSize) {
            if (tmpSize.width / tmpSize.height == rate) {
                return tmpSize;
            }
        }
        return null;
    }

3. Perform camera preview

Camera preview is divided into three steps:

  • Implement the callback of surfaceHolder
  • Set the surfaceHolder as the display control of the camera
  • Turn on camera preview
 private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
 
        @Override
        public boolean isCreating() {
            return false;
        }
 
        @Override
        public void addCallback(Callback callback) {
        }
 
        @Override
        public void removeCallback(Callback callback) {
        }
 
        @Override
        public void setFixedSize(int width, int height) {
        }
 
        @Override
        public void setSizeFromLayout() {
        }
 
        @Override
        public void setFormat(int format) {
        }
 
        @Override
        public void setType(int type) {
        }
 
        @Override
        public void setKeepScreenOn(boolean screenOn) {
        }
 
        @Override
        public Canvas lockCanvas() {
            return null;
        }
 
        @Override
        public Canvas lockCanvas(Rect dirty) {
            return null;
        }
 
        @Override
        public void unlockCanvasAndPost(Canvas canvas) {
        }
 
        @Override
        public Surface getSurface() {
            return null;
        }
 
        @Override
        public Rect getSurfaceFrame() {
            return null;
        }
    };  
 
 private void restartPreview(SurfaceHolder holder) {
        if (camera != null) {
            if (holder.getSurface() == null) {
                return;
            }
 
            try {
                camera.stopPreview();
            } catch (Exception e) {
            }
 
            try {
                // 将surfaceViewHolder设置为camera的显示控件
                camera.setPreviewDisplay(holder);
 
                // 开启相机预览
                camera.startPreview();
                if (listener != null) {
                    listener.onStartPreview();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

4. Take pictures

To take a picture, you only need to call camera.takePicture().

Guess you like

Origin blog.csdn.net/xiaowang_lj/article/details/131822890