Android学習ノート---カメラ(2)

カメラのAPIと関連知識については前述しましたが、ここではカメラの例を説明します。

カメラを使用して Android でカメラ アプリケーションを開発する最も基本的なプロセスは次のとおりです。

  • open(int CameraId) を使用してカメラ インスタンスを取得します。
  • カメラ インスタンスのプレビュー クラスを設定します。これは SurfaceHolder オブジェクトであり、setPreviewDisplay(SurfaceHolder) によって設定されます。
  • startPreview() を呼び出してカメラ インスタンスのプレビューを開始します
  • takePicture() メソッドを呼び出して写真を撮ります。キャプチャされた画像データは Camera.PictureCallback() コールバックを通じて取得できます。
  • 撮影が完了したら、stopPreview() を呼び出してプレビューを停止し、release() を使用してカメラが占有しているリソースを解放する必要があります。

上記の手順は重要なプロセスです。カメラにはパブリック コンストラクターがありません。open() メソッドを通じてカメラ インスタンスを取得し、surfaceHolder プレビュー クラスを設定することのみが可能です。この手順が実装されていない場合、カメラは機能しません使用済み。カメラの使用が完了したら、release()を使用してカメラのリソースを解放する必要があります。以下、具体例を挙げて説明する。

次の例は次の手順に分かれています。

  • システム権限の設定
  • カメラのレイアウト
  • カメラのプレビュー設定
  • 写真を撮るカメラ

システム権限の設定

// 相机权限
<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" />

カメラのレイアウト

<?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>

カメラのプレビュー設定

カメラ プレビューの設定では、まずカメラとカメラ プレビュー サイズを取得し、SurfaceView を通じてカメラ プレビュー画面を表示する必要があります。

カメラを入手

/**
* 获取相机实例
* 
* @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;
}

最適なプレビュー サイズを取得する

1. カメラがサポートするすべてのプレビュー解像度を取得します

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

2. プレビューに適切な解像度を計算します。

この手順は、プレビューおよび写真撮影時に写真が変形しないように、SurfaceView と同じ解像度比で最大解像度サイズを取得することです。

    /**
     * 获取适合的分辨率
     *
     * @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. カメラプレビューを実行する

カメラのプレビューは 3 つのステップに分かれています。

  • surfaceHolderのコールバックを実装する
  • surfaceHolder をカメラのディスプレイ コントロールとして設定します
  • カメラのプレビューをオンにする
 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.写真を撮る

写真を撮るには、camera.takePicture() を呼び出すだけです。

おすすめ

転載: blog.csdn.net/HaveFun_Wine/article/details/129821362