Hanzo
Hanzo

Reputation: 1899

Set correct orientation to preview camera and final result image

I'm developing my custom camera app and I'm having problems with the orientation.

When the phone is in portrait orientation the preview screen and result image shows in landscape

enter image description here

When the phone is in left landscape orientation the preview screen and result image shows correctly

enter image description here

When the phone is in right landscape orientation the preview screen and result image shows in landscape mode but flipped vertically

enter image description here

I've read about changing orientation with setDisplayorientation but I have not managed to fix it.

Can someone help me?

Thanks for the help

This is the code of the camera activity that starts preview

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // TODO Auto-generated method stub
        System.out.println("!!!!!!!CAMBIO!!!!!!!!" );
        initPreview(width, height);
        startPreview();
    }


    private void initPreview(int width, int height) {
        if (myCamera!=null && mySurfaceHolder.getSurface()!=null) {
            try {
                myCamera.setPreviewDisplay(mySurfaceHolder);
            }
            catch (Throwable t) {
                Log.e("PreviewDemo-surfaceCallback",
                        "Exception in setPreviewDisplay()", t);
                Toast
                .makeText(CameraHandler.this, t.getMessage(), Toast.LENGTH_LONG)
                .show();
            }

            if (!cameraConfigured) {
                Camera.Parameters parameters=myCamera.getParameters();
                Camera.Size size=getBestPreviewSize(width, height,
                        parameters);

                if (size!=null) {

                    parameters.setPreviewSize(size.width, size.height);

                    myCamera.setParameters(parameters);
                    cameraConfigured=true;
                }
            }
        }
    }

    private void startPreview() {
        if (cameraConfigured && myCamera!=null) {
            myCamera.startPreview();
            inPreview=true;
        }
    }

private Camera.Size getBestPreviewSize(int width, int height,  Camera.Parameters parameters) {

        Camera.Size result=null;

        for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
            System.out.println("Soportados " + size.width + "x" + size.height);
            if (size.width<=width && size.height<=height) {
                if (result==null) {
                    result=size;
                }
                else {
                    int resultArea=result.width*result.height;
                    int newArea=size.width*size.height;

                    if (newArea>resultArea) {
                        result=size;
                    }
                }
            }
        }

        return(result);
    }

Upvotes: 3

Views: 2611

Answers (1)

Alex Cohn
Alex Cohn

Reputation: 57203

The code sample for setDisplayorientation() is in the main documentation:

If you want to make the camera image show in the same orientation as the display, you can use the following code.

 public static void setCameraDisplayOrientation(Activity activity,
         int cameraId, android.hardware.Camera camera) {
     android.hardware.Camera.CameraInfo info =
             new android.hardware.Camera.CameraInfo();
     android.hardware.Camera.getCameraInfo(cameraId, info);
     int rotation = activity.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;
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
         result = (info.orientation + degrees) % 360;
         result = (360 - result) % 360;  // compensate the mirror
     } else {  // back-facing
         result = (info.orientation - degrees + 360) % 360;
     }
     camera.setDisplayOrientation(result);
 }

Starting from API level 14, this method can be called when preview is active.

This does not apply to the picture captured with Camera.takePicture(). For that, you can use Camera.Parameters.setRotation(). Unfortunately, some devices only set an EXIF rotation flag according to this, and even more unfortunately, some popular image viewers ignore this flag. In such case, you must rotate the resulting JPEG yourself. For that, you can use a Java MediaUtil library, see e.g. https://stackoverflow.com/a/15302674/192373.

Upvotes: 2

Related Questions