Search code examples
androidcameraandroid-camera2

Camera2 API Issue


I make some camera App use camera2 APi example camera2 api google sample, so my camera output not full screen

Autofit texture view not full screen

then i read from camera2 api isue to solve that i have to change this in Onmeasure at AUtofitTextureView class:

if (width < height * mRatioWidth / mRatioHeight) {

from < to > so like here :

 if (width > height * mRatioWidth / mRatioHeight) {

then my camera view fix to fullscreen camera preview full scren

but Now i have other issue, my capture image is bigger than my preview.

please check my screen capture from my app

  1. my camera preview not full screen

sdsds

  1. my capture image if camera preview not full screen

sdsdds 3. my camera preview Full screen after change on Meisure method

sdsdsd

  1. my capture image from camera preview after change on Meisure method. dsssdds

the problem is that make my capture image not same with my camera preview


Solution

  • I have tried by the following way, here is shared my code for maintaining the aspect ratio of 16:9,18:9,19:9.hope this answer will help, based on the device resolution choice ArrayList have max to min resolution this is the way I resolve the preview stretch issue.

    //Samsung-S6-choices[0]
    //Samsung-S7-edge-choices[6]
    //OnePlus-5T-choices[15]
    /*
     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose
     * width and height are at least as large as the respective requested values, and whose aspect
     * ratio matches with the specified value.
     *
     * @param choices     The list of sizes that the camera supports for the intended output class
     * @param width       The minimum desired width
     * @param height      The minimum desired height
     * @param aspectRatio The aspect ratio
     * @return The optimal {@code Size}, or an arbitrary one if none were big enough
     */
    private  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();
        double ratio = (double) h / w;
        int loopCounter=0;
        for (Size size : choices) {
            int orientation = getActivityContext.getResources().getConfiguration().orientation;
            if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                //if((size.getWidth()/16) == (size.getHeight()/9) && size.getWidth() <=720) {
                //if((size.getWidth()/16) == (size.getHeight()/9) && size.getWidth() <=3840 ) {
                //if((size.getWidth()/16) == (size.getHeight()/9) && size.getWidth() <=5120 ) {//Retina 5K
                if((size.getWidth()/16) == (size.getHeight()/9) && size.getWidth() <=7680 ) {//8K UHDTV Super Hi-Vision
                    Log.e(TAG1, "chooseOptimalSize:"+size);
                    return size;
                }
            } else {
                Log.e(TAG1, "chooseOptimalSize:--given--"+size);
                DisplayMetrics metrics = getActivityContext.getResources().getDisplayMetrics();
                float mCameraAspectRatio = ((float)metrics.heightPixels / (float)metrics.widthPixels);
                Log.e(TAG1, "chooseOptimalSize:--AspectRatio--"+mCameraAspectRatio);
                if((size.getWidth()/16) == (size.getHeight()/9) && ((size.getWidth() <=1280)||(size.getHeight()<=1920))) {
                    //if((size.getWidth()/16) == (size.getHeight()/9) && (size.getWidth() <=4320 ) ) {//8K UHDTV Super Hi-Vision
                    //if((size.getWidth()/16) == (size.getHeight()/9) && (size.getWidth() <=2880 ) ) {//Retina 5K
                    //if((size.getWidth()/16) == (size.getHeight()/9) && (size.getWidth() <=2160 ) ) {
                    //if((size.getWidth()/16) == (size.getHeight()/9) && (size.getWidth() <=1280 ) ) {
                    //if((size.getWidth()/16) == (size.getHeight()/9) && (size.getWidth() <=4480 && size.getWidth() >=1280) ) {
                    Log.e(TAG1, "chooseOptimalSize:"+size+"-16:9");
                    return size;
                }else if((size.getWidth()/18) == (size.getHeight()/9) && ((size.getWidth() <=3840)||(size.getHeight()<=2160))) {
                    Log.e(TAG1, "chooseOptimalSize:"+size+"-18:9");
                    return size;
                }else if((size.getWidth()/18.5) == (size.getHeight()/9) && ((size.getWidth() <=3840)||(size.getHeight()<=2160))) {
                    Log.e(TAG1, "chooseOptimalSize:"+size+"-18.5:9");
                    return size;
                }else if((size.getWidth()/19) == (size.getHeight()/9) && ((size.getWidth() <=3840)||(size.getHeight()<=2160))) {
                    Log.e(TAG1, "chooseOptimalSize:"+size+"-19:9");
                    return size;
                }else if((size.getWidth()/19.5) == (size.getHeight()/9) && ((size.getWidth() <=3840)||(size.getHeight()<=2160))) {
                    Log.e(TAG1, "chooseOptimalSize:"+size+"-19.5:9");
                    return size;
                }else{
                    Log.e(TAG1, "chooseOptimalSize"+" not proper aspect resolution");
                    Log.e(TAG1, "chooseOptimalSize"+" ---=>Width---=>"+size.getWidth());
                    Log.e(TAG1, "chooseOptimalSize"+" ---=>Height---=>"+size.getHeight());
                }
                //2340
            }
    
            if(screenWidth==size.getWidth()){
                Log.e(TAG1, loopCounter+".choose:width Matched:"+screenWidth+"="+size.getWidth());
            }else{
                Log.e(TAG1, loopCounter+".choose:width Not Matched:"+screenWidth+"="+size.getWidth());
            }
    
            if(screenHeight==size.getHeight()){
                Log.e(TAG1, loopCounter+".choose:height Matched:"+screenHeight+"="+size.getHeight());
            }else{
                Log.e(TAG1, loopCounter+".choose:height Not Matched:"+screenHeight+"="+size.getHeight());
            }
            loopCounter++;
        }
        // Pick the smallest of those, assuming we found any
        if (bigEnough.size() > 0) {
            return Collections.min(bigEnough, new CompareSizesByArea());
        } else {
            Log.e(TAG1, "Couldn't find any suitable preview size");
            return choices[0];
        }
    }
    
    
    /*
     * Compares two {@code Size}s based on their areas.
     */
    static class CompareSizesByArea implements Comparator<Size> {
        @Override
        public int compare(Size lhs, Size rhs) {
            // We cast here to ensure the multiplications won't overflow
            return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
                    (long) rhs.getWidth() * rhs.getHeight());
        }
    }
    

    Hope it will help, please leave a comment, in case of any issue.