Android Camera Preview Stretched

I’m using this method -> based on API Demos to get my Preview Size:

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio=(double)h / w;

        if (sizes == null) return null;

        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        for (Camera.Size size : sizes) {
            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);
            }
        }

        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

As you can see you have to input width and height of your screen. This method will calculate screen ratio based on those values and then from the list of supportedPreviewSizes it will choose the best for you from avaliable ones. Get your supportedPreviewSize list in place where Camera object isn’t null by using

mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();

And then on in onMeasure you can get your optimal previewSize like that:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(width, height);

        if (mSupportedPreviewSizes != null) {
           mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
        }
    }

And then (in my code in surfaceChanged method, like I said I’m using API Demos structure of CameraActivity code, you can generate it in Eclipse):

Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
mCamera.setParameters(parameters);
mCamera.startPreview();

And one hint for you, because I did almost the same app like you. Good practice for Camera Activity is to hide StatusBar. Applications like Instagram are doing it. It reduces your screen height value and change your ratio value. It is possible to get strange Preview Sizes on some devices (your SurfaceView will be cut a little)


And to answer your question, how to check if your preview ratio is correct? Then get height and width of parameters that you set in:

mCamera.setParameters(parameters);

your set ratio is equal to height/width. If you want camera to look good on your screen then height/width ratio of parameters that you set to camera must be the same as height(minus status bar)/width ratio of your screen.

Leave a Comment