美文网首页
安卓 camera2 textureView imageread

安卓 camera2 textureView imageread

作者: 汉堡a | 来源:发表于2020-05-02 23:09 被阅读0次

    创建一个 CameraProvider类

    package com.example.opencv_cpp_test;
    
    import android.Manifest;
    import android.annotation.SuppressLint;
    import android.app.Activity;
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.ImageFormat;
    import android.graphics.Matrix;
    import android.graphics.RectF;
    import android.graphics.SurfaceTexture;
    import android.hardware.camera2.CameraAccessException;
    import android.hardware.camera2.CameraCaptureSession;
    import android.hardware.camera2.CameraCharacteristics;
    import android.hardware.camera2.CameraDevice;
    import android.hardware.camera2.CameraManager;
    import android.hardware.camera2.CaptureRequest;
    import android.hardware.camera2.params.StreamConfigurationMap;
    import android.media.Image;
    import android.media.ImageReader;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.util.Log;
    import android.util.Size;
    import android.view.Surface;
    import android.view.TextureView;
    
    import java.nio.ByteBuffer;
    import java.util.Arrays;
    
    import static androidx.core.content.ContextCompat.checkSelfPermission;
    
    
    public class CameraProvider {
        private Activity mContext;
        private String mCameraId;
        private Handler mCameraHandler;
        private CameraDevice mCameraDevice;
        private TextureView mTextureView;
        private CaptureRequest.Builder mPreviewBuilder;
        private Size previewSize;
    
        ImageReader mImageReader;
        private ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader reader) {
    //获取最新的一帧的Image
                Image image = reader.acquireLatestImage();
                Log.e("cam123","onImageAvailable");
                if(image!=null){
    
                    image.close();
                }
            }
        };
    
        public CameraProvider(Activity mContext) {
            this.mContext = mContext;
            //创建了一个Thread来供Camera运行使用,使用HandlerThread而不使用Thread是因为HandlerThread给我们创建了Looper,不用我们自己创建了。
            HandlerThread handlerThread = new HandlerThread("camera");
            handlerThread.start();
            mCameraHandler = new Handler(handlerThread.getLooper());
        }
    
        public void initTexture(TextureView textureView) {
            mTextureView = textureView;
    
            textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
                @Override
                public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                    openCamera(width, height);
                }
    
                @Override
                public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
                }
    
                @Override
                public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                    return false;
                }
    
                @Override
                public void onSurfaceTextureUpdated(SurfaceTexture surface) {
                }
            });
        }
        private void configureTransform(int viewWidth, int viewHeight) {
    
            int rotation = Surface.ROTATION_90;
            Matrix matrix = new Matrix();
            RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
            RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());
            float centerX = viewRect.centerX();
            float centerY = viewRect.centerY();
            if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
                bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
                matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
                float scale = Math.max(
                        (float) viewHeight / previewSize.getHeight(),
                        (float) viewWidth / previewSize.getWidth());
                matrix.postScale(scale, scale, centerX, centerY);
                matrix.postRotate(90 * (rotation - 2), centerX, centerY);
            } else if (Surface.ROTATION_180 == rotation) {
                matrix.postRotate(180, centerX, centerY);
            }
            mTextureView.setTransform(matrix);
        }
        /**
         * surface ready的时候开启Camera
         *
         * @param width  surface的宽
         * @param height surface的高
         */
        @SuppressLint("MissingPermission")
        private void openCamera(int width, int height) {
            CameraManager cameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
    
            try {
                for (String cameraId : cameraManager.getCameraIdList()) {
                    //描述相机设备的属性类
                    CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
                    //获取是前置还是后置摄像头
                    Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
                    //使用后置摄像头
                    if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) {
                        StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                        if (map != null) {
                            //previewSize = CameraUtil.getOptimalSize(map.getOutputSizes(SurfaceTexture.class), width, height);
                            previewSize=new Size(mTextureView.getWidth(),mTextureView.getHeight());
                            mCameraId = cameraId;
                        }
                    }
                }
                mImageReader = ImageReader.newInstance(previewSize.getWidth(), previewSize.getHeight(),
                        ImageFormat.JPEG, 2);
                mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mCameraHandler);
                cameraManager.openCamera(mCameraId, mStateCallback, mCameraHandler);
                configureTransform(previewSize.getWidth(),previewSize.getHeight());
            } catch (CameraAccessException r) {
    
            }
        }
        /**
         * 状态回调
         */
        private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
            @Override
            public void onOpened(CameraDevice camera) {
                mCameraDevice = camera;
                SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
                surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
                Surface previewSurface = new Surface(surfaceTexture);
                try {
                    mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                    //如果需要多个surface可以add多个
                    mPreviewBuilder.addTarget(previewSurface);
                    mPreviewBuilder.addTarget(mImageReader.getSurface());
                    //mPreviewBuilder.set(CaptureRequest.O, 270);
                    mCameraDevice.createCaptureSession(Arrays.asList(previewSurface,mImageReader.getSurface()), mStateCallBack, mCameraHandler);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
    
            @Override
            public void onDisconnected(CameraDevice camera) {
                camera.close();
            }
    
            @Override
            public void onError(CameraDevice camera, int error) {
                camera.close();
            }
        };
    
        private CameraCaptureSession.StateCallback mStateCallBack = new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(CameraCaptureSession session) {
                CaptureRequest request = mPreviewBuilder.build();
                try {
                    //获取一个Image,one-shot
    //                session.capture(request, null, mCameraHandler);
                    //开启获取Image,repeat模式
                    session.setRepeatingRequest(request, null, mCameraHandler);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
    
            @Override
            public void onConfigureFailed(CameraCaptureSession session) {}
        };
        /**
         * 记得关掉Camera
         */
        public void closeCamera() {
            mCameraDevice.close();
        }
    }
    
     
    

    通过这个类可以把摄像头预览绑定到textureView上,然后的话。记得申请权限。我是 事先申请好了的。

    使用的话应该看得懂吧 先 new,再init传入textureView就好了。

    然后旋转的设置在configureTransform里面。

    关键语句

    mPreviewBuilder.addTarget(previewSurface);
                    mPreviewBuilder.addTarget(mImageReader.getSurface());
                    //mPreviewBuilder.set(CaptureRequest.O, 270);
                    mCameraDevice.createCaptureSession(Arrays.asList(previewSurface,mImageReader.getSurface()), mStateCallBack, mCameraHandler);
    

    这里要注意的是,加了两种surface。下面也要相应地加入包含这两种的list

    相关文章

      网友评论

          本文标题:安卓 camera2 textureView imageread

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