美文网首页android
SurfaceView 和 TextureView 预览came

SurfaceView 和 TextureView 预览came

作者: 超威蓝猫l | 来源:发表于2018-03-01 15:50 被阅读0次

    SurfaceView 和 TextureView 预览camera数据得方式非常相似

    在SurfaceView中就是在surface创建得回调开启摄像头 并将摄像头数据送到holder 中
    在TextureView中就是在surfaceTexture可用得回调中开启摄像头 并将摄像头得数据送到surface中

    SurfaceView预览代码:

    import android.hardware.Camera;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.Display;
    import android.view.Surface;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.Window;
    import android.view.WindowManager;
    
    import com.lemniscate.audio_and_video_demo.R;
    
    import java.io.IOException;
    import java.util.List;
    
    public class SurfaceViewCameraActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    
        private SurfaceView sv;
        private SurfaceHolder holder;
        private Camera mCamera;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.activity_surface_view_camera);
    
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    
            sv = findViewById(R.id.sv);
            holder = sv.getHolder();
            holder.addCallback(this);
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            mCamera = getCamera();
            if (mCamera != null) {
                try {
                    mCamera.setPreviewDisplay(holder);//预览数据送到holder
                    mCamera.startPreview();
                    mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                        @Override
                        public void onPreviewFrame(byte[] data, Camera camera) {
                              //得到的预览数据
                        }
                    });
    
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            //这里变化的时候转换方向 等
            refreshCamera();
            int displayOrientation = getDisplayOrientation();
            mCamera.setDisplayOrientation(displayOrientation);
            Camera.Parameters params = mCamera.getParameters();
            Camera.Size optimalPreviewSize = getOptimalPreviewSize(mCamera.getParameters().getSupportedPreviewSizes(), width, height);
            params.setPictureSize(optimalPreviewSize.width, optimalPreviewSize.height);
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            holder.removeCallback(this);
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    
    //获取最佳的分辨率 而且是16:9的
        private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
            final double ASPECT_TOLERANCE = 0.75;
            double targetRatio = (double) w / h;
            if (sizes == null)
                return null;
    
            Camera.Size optimalSize = null;
            double minDiff = Double.MAX_VALUE;
    
            int targetHeight = h;
    
            // Try to find an size match aspect ratio and size
            for (Camera.Size size : sizes) {
                double ratio = (double) size.width / size.height;
                if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                    continue;
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
    
            // Cannot find the one match the aspect ratio, ignore the requirement
            if (optimalSize == null) {
                minDiff = Double.MAX_VALUE;
                for (Camera.Size size : sizes) {
                    if (Math.abs(size.height - targetHeight) < minDiff) {
                        optimalSize = size;
                        minDiff = Math.abs(size.height - targetHeight);
                    }
                }
            }
            return optimalSize;
        }
        //这里是一小段算法算出摄像头转多少都和屏幕方向一致
        private int getDisplayOrientation() {
            WindowManager windowManager = getWindowManager();
            Display defaultDisplay = windowManager.getDefaultDisplay();
            int orientation = defaultDisplay.getOrientation();
            int degress = 0;
            switch (orientation) {
                case Surface.ROTATION_0:
                    degress = 0;
                    break;
                case Surface.ROTATION_90:
                    degress = 90;
                    break;
                case Surface.ROTATION_180:
                    degress = 180;
                    break;
                case Surface.ROTATION_270:
                    degress = 270;
                    break;
            }
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            android.hardware.Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, cameraInfo);
            int result = (cameraInfo.orientation - degress + 360) % 360;
            return result;
        }
    
        private void refreshCamera() {
            if (holder.getSurface() == null) {
                //preview surface does not exist
                return;
            }
            mCamera.stopPreview();
    
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        private Camera getCamera() {
            return Camera.open();
        }
    }
    

    TextureView的代码

    import android.graphics.SurfaceTexture;
    import android.hardware.Camera;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.Display;
    import android.view.Surface;
    import android.view.TextureView;
    import android.view.WindowManager;
    
    import com.lemniscate.audio_and_video_demo.R;
    
    import java.io.IOException;
    import java.util.List;
    
    public class TextureViewCameraActivity extends AppCompatActivity {
    
        private TextureView textureView;
    
        private SurfaceTexture surfaceTexture;
        private Camera camera;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_texture_view_camera);
    
            textureView = findViewById(R.id.textureView);
            textureView.setSurfaceTextureListener(new MySurfaceTextureViewListener());
        }
    
        private class MySurfaceTextureViewListener implements TextureView.SurfaceTextureListener {
    
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                surfaceTexture = surface;
                initCamera();
            }
    
            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
                int displayOrientation = getDisplayOrientation();
                camera.setDisplayOrientation(displayOrientation);
                List<Camera.Size> supportedPreviewSizes = camera.getParameters().getSupportedPreviewSizes();
                Camera.Size optimalPreviewSize = getOptimalPreviewSize(supportedPreviewSizes, width, height);
                camera.getParameters().setPictureSize(optimalPreviewSize.width, optimalPreviewSize.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) {
    
            }
        }
    
        这里删除掉一些上面有的重复方法
    

    相关文章

      网友评论

        本文标题:SurfaceView 和 TextureView 预览came

        本文链接:https://www.haomeiwen.com/subject/fvogxftx.html