Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Camera Surface View Images Look Stretched

In portrait mode, the images look vertically stretched and in landscape mode it looks horizontally stretched.

Although after capturing the image appears in proper size.

How to resolve this issue?

like image 517
Manjeet Avatar asked Jun 22 '12 07:06

Manjeet


2 Answers

You need to choose a preview size that matches your display size. I would suggest changing the preview size setting to match your SurfaceView rather than the other way around. While the preview data is just fine, it's not distorted, it will look distorted when flung onto a surface with different aspect ratio.

If you have a full-screen view, then you should find the camera has a preview size matching that size -- at the least there will be one with the same aspect ratio. For example if your screen is 640x480 then a 320x240 preview size will not appear stretched on a full-screen SurfaceView.

like image 157
Sean Owen Avatar answered Nov 03 '22 12:11

Sean Owen


You have to constrain your preview size based on (1) available preview sizes (2) your view. Here is my solution if you still need it:

private class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    private void startPreview() {
        try {
        /**
         * Orientation should be adjusted, see http://stackoverflow.com/questions/20064793/how-to-fix-camera-orientation/26979987#26979987
         */

            Camera.Parameters parameters = mCamera.getParameters();
            List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
            Camera.Size previewSize = null;
            float closestRatio = Float.MAX_VALUE;

            int targetPreviewWidth = isLandscape() ? getWidth() : getHeight();
            int targetPreviewHeight = isLandscape() ? getHeight() : getWidth();
            float targetRatio = targetPreviewWidth / (float) targetPreviewHeight;

            Log.v(TAG, "target size: " + targetPreviewWidth + " / " + targetPreviewHeight + " ratio:" + targetRatio);
            for (Camera.Size candidateSize : previewSizes) {
                float whRatio = candidateSize.width / (float) candidateSize.height;
                if (previewSize == null || Math.abs(targetRatio - whRatio) < Math.abs(targetRatio - closestRatio)) {
                    closestRatio = whRatio;
                    previewSize = candidateSize;
                }
            }

            Log.v(TAG, "preview size: " + previewSize.width + " / " + previewSize.height);
            parameters.setPreviewSize(previewSize.width, previewSize.height);
            mCamera.setParameters(parameters);
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }
 }
like image 44
Louis GRIGNON Avatar answered Nov 03 '22 13:11

Louis GRIGNON