Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Camera2 full screen preview and image capture

Tags:

android

camera

I am using the sample code for Camera2, and I was wondering how I can make the preview and captured image in full screen? This SO question seems to solve it in video mode, but I can't find any solution for image captures. The sample fragment has a blue area at the bottom and also has the status bas. I want to hide both of these and use the entire screen to show the preview, and also capture the image in full screen size.

like image 606
Kæmpe Klunker Avatar asked Feb 05 '23 04:02

Kæmpe Klunker


2 Answers

Eddy is correct about the aspect ratio.The camera sensor is 4:3. The screen is usually 16:9. The sample code choose to show the entire camera preview, so part of the screen is not filled. You need to stretch to fill the whole screen, however in that case the images captured include areas not shown in the preview.

To view it in full screen, in the AutoFitTextureView, change the onMeasure method to this:

    @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);
                setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
            } else {
                //setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
                setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
            }
        }
    }

Update: As pointed out by Eddy, this will show the upper left part of the camera preview on the full screen, leaving the bottom and right side out of the view, the result is that the image is off center. In my particular case the subject needs to be centered horizontally, so I modified the transform matrix to center the subject horizontally. Here is the code:

// adjust the x shift because we are not showing the whole camera sensor on the screen, need to center the capture area
    int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
    Log.d(TAG, "screen width " + screenWidth);
    int xShift = (viewWidth - screenWidth)/2;
    matrix.setTranslate(-xShift, 0);

        mTextureView.setTransform(matrix);
like image 119
Ray Avatar answered Feb 15 '23 12:02

Ray


Note that the aspect ratio of the camera sensor and the aspect ratio of your device screen most often do not match - sensors are generally 4:3 ratio and screens are generally around 16:9. Though there is wide variation in both.

Since the aspect ratios don't match, you'll need to decide if you're going to have black bars, or zoom the camera preview so that it fills the screen (but some part of the image is not visible).

In any case, to have the preview be full-screen, you just need to have the TextureView (or SurfaceView) be the entire layout. So basically, edit this layout file: fragment_camera2_basic.xml, remove all the other Views, and remove references to them in the source code. Or change them to be on top of the TextureView, not next to - this is all standard Android UI layout stuff. And you'll need to make your Activity be full-screen.

By default, AutoFillTextureView will try to maintain aspect ratio, so it'll produce black bars. If you want no black bars, then you'll have to change AutoFillTextureView, which is not straightforward, and I won't get into it here.

like image 45
Eddy Talvala Avatar answered Feb 15 '23 12:02

Eddy Talvala