基於相機錄制視頻程式(Camera Video Recording Program),在程式內通過 Android Camera 拍攝預覽中設置 setPreviewCallback 實現 onPreviewFrame 接口,實時截取每一幀視頻流數據 preview 功能是 camera 功能的基礎,相機進入拍照狀態必需要在 preview 之後,且用戶的體驗很大程度上與 preview 的幀率以及解析度有關。
相機預覽回調程式(Camera Preview Callback Program) |
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; } } |
沒有留言:
張貼留言