android SurfaceView&TextureView鏡頭預覽

上一篇文章簡單的寫了一點調用系統(tǒng)攝像頭錄制視頻和使用原生videoView播放視頻的方法。那么這篇文章繼續(xù)完成未完成的作業(yè)。

使用SurfaceView實現(xiàn)鏡頭的預覽

布局文件只需要一個SurfaceView

<SurfaceView
        android:id="@+id/surface_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

Activity實現(xiàn)回調方法

implements SurfaceHolder.Callback

注冊回調

@BindView(R.id.surface_view)
SurfaceView mSurfaceView;//預覽窗口
Camera camera;
//baseActivity中的方法,也可以直接寫在onCreate()中
   @Override
    protected void initView() {
        mSurfaceView.getHolder().addCallback(this);
    }

在創(chuàng)建的回調中去開啟鏡頭的預覽

 @Override
    public void surfaceCreated(SurfaceHolder holder) {
        camera = Camera.open(BACK);
        camera.setDisplayOrientation(90);
        try {
            camera.setPreviewDisplay(holder);
            camera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.release();
    }

使用TextureView去開啟鏡頭瀏覽

首先還是定義TextureView 和Camera

TextureView textureView;
Camera camera;

定義一個TextureView.SurfaceTextureListener,并在此處開啟預覽

  private class MySurfaceTextureViewListener implements TextureView.SurfaceTextureListener {

        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            try {
                  camera.setPreviewTexture(surfaceTexture);
                  camera.startPreview();
                  } catch (IOException e) {
                        e.printStackTrace();
                          }
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
           
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            surface.release();
            camera.setPreviewCallback(null);
            camera.stopPreview();
            camera.release();
            camera = null;
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {

        }
    }

初始化布局并且設置監(jiān)聽器,打開Camera

   //baseActivity中的方法,也可以直接寫在onCreate()中
   @Override
    protected void initView() {
        textureView.setSurfaceTextureListener(new MySurfaceTextureViewListener());
        camera = Camera.open();
        camera.setDisplayOrientation(90);
    }
切換前后攝像頭

可能寫得很復雜,見諒

private static final int FRONT = 1;//前置攝像頭標記
private static final int BACK = 0;//后置攝像頭標記
private int currentCameraType = BACK;//當前打開的攝像頭標記

private void changeCamera() throws IOException{
        //切換前后攝像頭
        int cameraCount = 0;
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        cameraCount = Camera.getNumberOfCameras();//得到攝像頭的個數(shù)

        for(int i = 0; i < cameraCount; i++   ) {
            Camera.getCameraInfo(i, cameraInfo);//得到每一個攝像頭的信息
            if(currentCameraType == BACK) {
                //現(xiàn)在是后置,變更為前置
                if(cameraInfo.facing  == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表攝像頭的方位,CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                    camera.stopPreview();//停掉原來攝像頭的預覽
                    camera.release();//釋放資源
                    camera = null;//取消原來攝像頭
                    camera = Camera.open(i);//打開當前選中的攝像頭
                    camera.setDisplayOrientation(90);
                    try {
                        camera.setPreviewDisplay(mSurfaceView.getHolder());//通過surfaceview顯示取景畫面
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    camera.startPreview();//開始預覽
                    currentCameraType = FRONT;
                    break;
                }
            } else {
                //現(xiàn)在是前置, 變更為后置
                if(cameraInfo.facing  == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表攝像頭的方位,CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                    camera.stopPreview();//停掉原來攝像頭的預覽
                    camera.release();//釋放資源
                    camera = null;//取消原來攝像頭
                    camera = Camera.open(i);//打開當前選中的攝像頭
                    camera.setDisplayOrientation(90);
                    try {
                        camera.setPreviewDisplay(mSurfaceView.getHolder());//通過surfaceview顯示取景畫面
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    camera.startPreview();//開始預覽
                    currentCameraType = BACK;
                    break;
                }
            }

        }
    }

取到NV21的回調

Android 中Google支持的 Camera Preview Callback的YUV常用格式有兩種:一個是NV21,一個是YV12。Android一般默認使用YCbCr_420_SP的格式(NV21)。

配置回調格式

Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewFormat(ImageFormat.NV21);
camera.setParameters(parameters);

在 Camera 在 release 之前設置 PreviewCallback 即可,bytes的數(shù)據(jù)就是NV21回調數(shù)據(jù)

camera.setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] bytes, Camera camera) {
                        
                    }
                });
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容