Custom camera stretches the photo

198 Views Asked by At

I come to you because my custom camera has a problem : the image is stretched. In portrait orientation camera has vertical elongated/stretched. In landscape orientation camera has horizontal elongated/stretched.

Please,help me.

Here is code of my camera:

public class CustomCamera extends Activity {

    SurfaceView sv;
    SurfaceHolder holder;
    HolderCallback holderCallback;
    static Camera camera = null;
    private boolean hasCamera = false;
    Button shotButton;

    int CAMERA_ID = 0;
    final boolean FULL_SCREEN = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.custom_camera_activity2);

        shotButton = (Button) findViewById(R.id.btnTakePicture);

        shotButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                try {
                    camera.autoFocus(new Camera.AutoFocusCallback() {

                        @Override
                        public void onAutoFocus(boolean success, Camera camera) {
                            camera.takePicture(null, null, new Camera.PictureCallback() {

                                @Override
                                public void onPictureTaken(byte[] data, Camera camera) {
                                    try {
                                        Intent intent = new Intent();
                                        intent.putExtra("data", data);
                                        setResult(RESULT_OK, intent);
                                        finish();
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            });
                        }
                    });
                } catch (NullPointerException ex) {
                    ex.printStackTrace();
                    finish();
                }
            }
        });

        sv = (SurfaceView) findViewById(R.id.surfaceView);
        holder = sv.getHolder();
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        holderCallback = new HolderCallback();

        int numCameras = Camera.getNumberOfCameras();
        if (numCameras > 0) {
            switch (numCameras) {
                case 1:
                    CAMERA_ID = 0;
                    break;
                case 2:
                    CAMERA_ID = 1;
                    break;
            }
            hasCamera = true;
        } else {
            hasCamera = false;
        }
        holder.addCallback(holderCallback);
    }

    @Override
    protected void onResume() {

        super.onResume();
        if (hasCamera) {
            try {
                camera = Camera.open(CAMERA_ID);
                setPreviewSize(FULL_SCREEN);
            } catch (Exception e) {
                e.printStackTrace();
                Log.d(Constant.DEBUG_TAG, "Failed to access to camera");
            }
        } else {
            Toast.makeText(this, "The device has no camera", Toast.LENGTH_SHORT).show();
            Log.d(Constant.DEBUG_TAG, "The device has no camera");
        }
    }

    @Override
    protected void onPause() {

        super.onPause();
        if (camera != null) {
            camera.stopPreview();
            camera.release();
        }
        camera = null;
    }

    class HolderCallback implements SurfaceHolder.Callback {

        @Override
        public void surfaceCreated(SurfaceHolder holder) {

            try {
                camera.setPreviewDisplay(holder);
                camera.startPreview();
            } catch (NullPointerException ex) {
                ex.printStackTrace();
                Log.d(Constant.DEBUG_TAG, "Failed to access to camera");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            try {
                camera.stopPreview();
                setCameraDisplayOrientation(CAMERA_ID);
                camera.setPreviewDisplay(holder);
                camera.startPreview();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
        }
    }

    void setPreviewSize(boolean fullScreen) {

        Display display = getWindowManager().getDefaultDisplay();
        boolean widthIsMax = display.getWidth() > display.getHeight();

        Size size = camera.getParameters().getPreviewSize();

        RectF rectDisplay = new RectF();
        RectF rectPreview = new RectF();
        rectDisplay.set(0, 0, display.getWidth(), display.getHeight());

        if (widthIsMax) {
            rectPreview.set(0, 0, size.width, size.height);
        } else {
            rectPreview.set(0, 0, size.height, size.width);
        }

        Matrix matrix = new Matrix();
        if (!fullScreen) {
            matrix.setRectToRect(rectPreview, rectDisplay,
                    Matrix.ScaleToFit.START);
        } else {
            matrix.setRectToRect(rectDisplay, rectPreview,
                    Matrix.ScaleToFit.START);
            matrix.invert(matrix);
        }
        matrix.mapRect(rectPreview);
        sv.getLayoutParams().height = (int) (rectPreview.bottom);
        sv.getLayoutParams().width = (int) (rectPreview.right);
    }

    void setCameraDisplayOrientation(int cameraId) {
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result = 0;

        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraId, info);

        if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
            result = ((360 - degrees) + info.orientation);
        } else
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                result = ((360 - degrees) - info.orientation);
                result += 360;
            }
        result = result % 360;
        camera.setDisplayOrientation(result);

        Camera.Parameters parameters = camera.getParameters();
        int rotate = (degrees + 270) % 360;
        parameters.setRotation(rotate);
        camera.setParameters(parameters);
    }
}

Here is my layout:

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cameraLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">
    <SurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true">
    </SurfaceView>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btnTakePicture"
        android:layout_alignBottom="@+id/surfaceView"
        android:layout_centerHorizontal="true"
        android:text="@string/take_picture" />
</RelativeLayout>
0

There are 0 best solutions below