Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • How to Implement Camera 2 API & Use its Method in Android App

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 1
    • 0
    • 1.84k
    Comment on it

    Camera 2 is advance API as Camera got deprecated. The interface is provided by the package named an android.hardware.camera2 to those individual camera devices which are connected to an android device. 

    This android.hardware.camera2 package models a camera device as a pipeline / instruction to capture a single frame, single image by taking an each input request and then provides an outputs in one capture result metadata packet, plus a set of output image buffers for the request.

     

     

    So, in this tutorial I will be helping you, how to implement Camera 2 API and use its method. 

    lets get started.

    In Xml,Texture View is used to see camera preview. Here i am going to use custom TextureView class.

    
    package com.example.camerafunctionality;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.TextureView;
    
    public class AutoFitTextureView extends TextureView {
    
        private int mRatioWidth = 0;
        private int mRatioHeight = 0;
    
        public AutoFitTextureView(Context context) {
            this(context, null);
        }
    
        public AutoFitTextureView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
      
        public void setAspectRatio(int width, int height) {
            if (width < 0 || height < 0) {
                throw new IllegalArgumentException("Size cannot be negative.");
            }
            mRatioWidth = width;
            mRatioHeight = height;
            requestLayout();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);
            if (0 == mRatioWidth || 0 == mRatioHeight) {
                setMeasuredDimension(width, height);
            } else {
                if (width < height * mRatioWidth / mRatioHeight) {
                    setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
                } else {
                    setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
                }
            }
        }
    
    }
    

    Remember to use this custom texture view in your xml. Now in my java class, first thing you need is permission to use camera from user. After you get the permission,  you need to call setSurfaceTextureListener of textureView.

     

     

     

                cameraTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
    

    SurfaceTextureListener will be called when TextureView is successfully added.

     

     

     

     private TextureView.SurfaceTextureListener mSurfaceTextureListener
                = new TextureView.SurfaceTextureListener() {
    
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
                                                  int width, int height) {
    
                Log.e("SurfaceTexture", "Available");
                openCamera(width, height);
            }
    
            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture,
                                                    int width, int height) {
    
                Log.e("SurfaceTexture", "SizeChanged");
            }
    
            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
                Log.e("SurfaceTexture", "Destroyed");
                return true;
            }
    
            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
                Log.e("SurfaceTexture", "Updated");
            }
        };

    SurfaceTextureAvailable will be called when Surface is available and then you can open the camera and set preview in it.

     

     

     

     @SuppressWarnings("MissingPermission")
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        private void openCamera(int width, int height) {
    
            CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
            try {
                String cameraId = manager.getCameraIdList()[0];
                // Choose the sizes for camera preview and video recording
                CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
                StreamConfigurationMap map = characteristics
                        .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                if (map != null) {
                    mVideoSize = chooseSize(map.getOutputSizes(MediaRecorder.class));
                    mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
                            width, height, mVideoSize);
    
                    int orientation = getResources().getConfiguration().orientation;
                    if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                        cameraTextureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight());
                    } else {
                        cameraTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth());
                    }
    
                    manager.openCamera(cameraId, mStateCallback, null);
    
                } else
                    Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
    
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

    Remember 1080p is the largest size used.

     

     

     

    
        private static Size chooseSize(Size[] choices) {
            for (Size size : choices) {
                if (size.getWidth() == size.getHeight() * 4 / 3 && size.getWidth() <= 1080) {
                    return size;
                }
            }
            Log.e("here", "Couldn't find any suitable video size");
            return choices[choices.length - 1];
        }
    
      
        private static Size chooseOptimalSize(Size[] choices, int width, int height, Size aspectRatio) {
            // Collect the supported resolutions that are at least as big as the preview Surface
            List<Size> bigEnough = new ArrayList<>();
            int w = aspectRatio.getWidth();
            int h = aspectRatio.getHeight();
            for (Size option : choices) {
                if (option.getHeight() == option.getWidth() * h / w &&
                        option.getWidth() >= width && option.getHeight() >= height) {
                    bigEnough.add(option);
                }
            }
    
            // Pick the smallest of those, assuming we found any
            if (bigEnough.size() > 0) {
                return Collections.min(bigEnough, new CompareSizesByArea());
            } else {
                Log.e("here", "Couldn't find any suitable preview size");
                return choices[0];
            }
        }

    CameraDevice.StateCallback is called when you have set height and width for texture view.

     

     

     

      private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
    
            @Override
            public void onOpened(@NonNull CameraDevice cameraDevice) {
                mCameraDevice = cameraDevice;
                startPreview();
            }
    
            @Override
            public void onDisconnected(@NonNull CameraDevice cameraDevice) {
                cameraDevice.close();
                mCameraDevice = null;
            }
    
            @Override
            public void onError(@NonNull CameraDevice cameraDevice, int error) {
                cameraDevice.close();
                mCameraDevice = null;
    
            }
        };

    Now when you will start previewing, camera will be opened and you will see images.

     

     

     

    private void startPreview() {
            if (null == mCameraDevice || !cameraTextureView.isAvailable() || null == mPreviewSize) {
                return;
            }
            try {
                SurfaceTexture texture = cameraTextureView.getSurfaceTexture();
                assert texture != null;
                texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
                mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
    
                Surface previewSurface = new Surface(texture);
                mPreviewBuilder.addTarget(previewSurface);
    
                mCameraDevice.createCaptureSession(Collections.singletonList(previewSurface),
                        new CameraCaptureSession.StateCallback() {
    
                            @Override
                            public void onConfigured(@NonNull CameraCaptureSession session) {
                                mPreviewSession = session;
                                updatePreview();
                            }
    
                            @Override
                            public void onConfigureFailed(@NonNull CameraCaptureSession session) {
    
                                finish();
                            }
                        }, null);
    
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

     

    That's all, you are done with camera2 Implementation. If you have any questions, please feel free to write in comment section below

    How to Implement Camera 2 API & Use its Method in Android App

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: