Camera display / preview in full screen does not maintain aspect ratio – image is skewed, stretched in order to fit on the screen

In a nutshell, you can do a camera preview in full screen however you’ll need to find out the appropriate sizes among the supported preview sizes by yourself, only if a customized camera preview is what you want.

For your question, according to the Android Developers — Camera

If you want to set a specific size for your camera preview, set this
in the surfaceChanged() method as noted in the comments above. When
setting preview size, you must use values from
getSupportedPreviewSizes(). Do not set arbitrary values in the
setPreviewSize() method.

It seemed you can’t manually pass the size you want other than the sizes provides by getSupportedPreviewSizes(). With a closer examine the sizes supported by your phones camera, you’ll find the ratio of sizes supported might not exactly the same as your screen’s ratio.

For example, Samsung Galaxy Ace II has 480×800 resolution screen, by reading the Size returned from getSupportedPreviewSizes(), its camera supports:

2560×1920

2560×1536

2048×1536

2048×1232

960×720

640×480

and if you want to display your camera preview in full screen correctly (without stretch), you’ll need to calculate, compare and apply the suitable ratio in these supported preview sizes.

Implementation of finding a proper preview size is not that complicated stuff. A common method for doing this would be something like this:

    /**
     * Calculate the optimal size of camera preview
     * @param sizes
     * @param w
     * @param h
     * @return
     */
    private Size getOptimalSize(List<Size> sizes, int w, int h) {

        final double ASPECT_TOLERANCE = 0.2;        
        double targetRatio = (double) w / h;         
        if (sizes == null)             
            return null;          
        Size optimalSize = null;         
        double minDiff = Double.MAX_VALUE;          
        int targetHeight = h;          
        // Try to find an size match aspect ratio and size         
        for (Size size : sizes) 
        {             
//          Log.d("CameraActivity", "Checking size " + size.width + "w " + size.height + "h");            
            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 (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff)
                {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight); 
                }
            }
        }

        SharedPreferences previewSizePref;
        if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
            previewSizePref = getSharedPreferences("PREVIEW_PREF",MODE_PRIVATE);
        } else {
            previewSizePref = getSharedPreferences("FRONT_PREVIEW_PREF",MODE_PRIVATE);
        }

        SharedPreferences.Editor prefEditor = previewSizePref.edit();
        prefEditor.putInt("width", optimalSize.width);
        prefEditor.putInt("height", optimalSize.height);

        prefEditor.commit();

//      Log.d("CameraActivity", "Using size: " + optimalSize.width + "w " + optimalSize.height + "h");            
        return optimalSize;     
    }

And you can also do the similar to find out the suitable camera sizes (the output picture size).

Note: I found the original version of the code above from Internet and I did some modification/optimisation for my own purpose.

Please let me know if this works for you.

Leave a Comment