2022年3月24日 星期四

Android Studio - 相機預覽回調程式(Camera Preview Callback Program)(七十四)

Android Studio - 相機預覽回調程式(Camera Preview Callback Program)(七十四):

基於相機錄制視頻程式(Camera Video Recording Program),在程式內通過 Android Camera 拍攝預覽中設置 setPreviewCallback 實現 onPreviewFrame 接口,實時截取每一幀視頻流數據 preview 功能是 camera 功能的基礎,相機進入拍照狀態必需要在 preview 之後,且用戶的體驗很大程度上與 preview 的幀率以及解析度有關。

相機預覽回調程式(Camera Preview Callback Program)
操作系統:Windows 7 64-bit 版本
  • 開發環境:Android Studio 4.0.1 版本
  • 原程式:C:\Development\Development_Android\Android_Project\DIY-Android-091-11d Camera Preview Callback
  • 程式:C:\Development\Development_Android\Android_Project\DIY-Android-091-11d Camera Preview Callback
  • 測試環境:Vivo(維沃)X5Max Android 4.4.4(KitKat)版本

  • Android 相機錄制視頻程式(Camera Video Recording Program)編程步驟:
    • 設定 Camera 許可權限後 - AndroidManifest.xml
    • 設定 SurfaceView 參數 - init_View()
    • 啟動 SurfaceView Callback - mSurfaceHolder.addCallback(this)
    • 打開 Camera - Camera.open()
    • 設置 Camera 參數 - setParameters()
    • StartPreview Camera 顯示 - setPreviewDisplay(surfaceHolder) → startPreview()
    • 加入 Preview Callback 功能
    • 設置功能在 onPreviewFrame(byte[] bytes, Camera camera)


    AndroidManifest.xml 獲取 Camera 許可權:

        <uses-feature android:name="android.hardware.camera" />

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

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


    activity_camera_previewcallback.xml:

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

     

        <SurfaceView

            android:id="@+id/activity_camera_surface"

            android:layout_width="match_parent"

            android:layout_height="match_parent" />

     

        <Button

            android:id="@+id/btn_camera_preview"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_marginTop="240dp"

            android:text="Preview Callback"

            app:layout_constraintEnd_toEndOf="parent"

            app:layout_constraintHorizontal_bias="0.535"

            app:layout_constraintStart_toStartOf="parent"

            app:layout_constraintTop_toTopOf="parent" />

     

    </androidx.constraintlayout.widget.ConstraintLayout>


    CameraPreviewCallback.java:

    package bugworkshop.blogspot.com.camera;

     

    import androidx.annotation.NonNull;

    import androidx.appcompat.app.AppCompatActivity;

    import android.os.Bundle;

    import android.util.Log;

     

    // Camera

    import android.hardware.Camera;

     

    // SurfaceView

    import android.view.SurfaceHolder;

    import android.view.SurfaceView;

    import android.view.View;

    import android.widget.Button;

    import android.widget.Toast;

     

    import java.io.ByteArrayOutputStream;

    import java.io.IOException;

     

    public class CameraPreviewCallback extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback{

     

        //private static final String tag = MainActivity.class.getSimpleName();

        private static final String TAG = "CameraActivity";

     

        // Camera

        private Camera mCamera;

     

        // SurfaceView

        private SurfaceView mSurfaceView;

        private SurfaceHolder mSurfaceHolder;

     

        private Button mbtn_camera_preview;

     

        private int iCount = 0;

     

        @Override

        protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_camera_previewcallback);

     

            mbtn_camera_preview = (Button)findViewById(R.id.btn_camera_preview);

     

            mbtn_camera_preview.setOnClickListener(new View.OnClickListener()

            {

                @Override

                public void onClick(View v) {

                Log.d(TAG, "MainActivity - CameraPreview");

                mCamera.setPreviewCallback(CameraPreviewCallback.this);

                }

            });

     

            init_View();

     

        }

     

        //@Override

        public void init_View() {

            Log.d(TAG, "CameraPreviewCallback - init_View()");

     

            mSurfaceView = (SurfaceView)findViewById(R.id.activity_camera_surface);

            mSurfaceHolder = mSurfaceView.getHolder();

            mSurfaceHolder.addCallback(this);

            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        }

     

        @Override

        public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {

            mCamera = Camera.open();

            if (mCamera != null) {

                Camera.Parameters p = mCamera.getParameters();

                p.setPreviewSize(640, 480);

                p.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);

                mCamera.setParameters(p);

            }

     

            try {

                mCamera.setPreviewDisplay(surfaceHolder);

                mCamera.startPreview();

            } catch (IOException e) {

                e.printStackTrace();

            }

     

        }

     

        @Override

        public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {

        }

     

        @Override

        public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {

        }

     

     

        @Override

        public void onPreviewFrame(byte[] bytes, Camera camera) {

            Log.d(TAG, "CameraPreviewCallback - onPreviewFrame");

            showToast("onPreviewFrame");

     

            Camera.Parameters parameters = mCamera.getParameters();

     

            switch (iCount/100) {

                case 0:

                    parameters.setColorEffect(Camera.Parameters.EFFECT_NONE);

                    showToast("Camera.Parameters.EFFECT_NONE");

                    mCamera.setParameters(parameters);

                    break;

                case 2:

                    parameters.setColorEffect(Camera.Parameters.EFFECT_AQUA);

                    showToast("Camera.Parameters.EFFECT_AQUA");

                    mCamera.setParameters(parameters);

                    break;

            }

                iCount ++;

                if (iCount > 300) iCount = 0;

        }

    }


    2022年 3月 24日(Thu)天氣報告
    氣溫:40.0°F / 4.0°C @ 07:00
    風速:每小時 3公里
    降雨機會:3%
    相對濕度:百分之 87%
    天氣:局部有雲

    沒有留言:

    張貼留言