简体   繁体   中英

How to set camera orientation in Android?

I've looked at other questions where people have asked this, but I wasn't sure what the best way to solve this problem was. After going through Android's guide to implement the camera, the camera preview I have is locked into landscape. I wanted to know how to adjust the camera orientation to mirror the orientation of the phone.

I tried this

camera.setDisplayOrientation(90);

And that locked the camera into portrait mode, so I need another solution (preferably one that works for most devices).

Also, how can I make it so the saved image shows up the same way as the preview? Right now if I use that line of code above to make the preview go to portrait, the saved image is still rotated for a landscape.

 Camera.Parameters params= mCamera.getParameters();
 params.set("rotation", 90); 
 mCamera.setParameters(params);

You need to take the orientation into account when determining what preview size to choose. For example, the getOptimalPreviewSize() from the CameraPreview of ApiDemos is oblivious to orientation, simply because their version of that app has the orientation locked to landscape. If you wish to let the orientation float, you need to reverse the target aspect ratio to match. So, where getOptimalPreviewSize() has this

double targetRatio=(double)width / height;

And

if (displayOrientation == 90 || displayOrientation == 270) {
  targetRatio=(double)height / width;
}

where displayOrientation is a value from 0 to 360, that I am determining from about 100 lines of some seriously ugly code, which is why I am wrapping all of this up in a reusable component that I'll publish shortly.

Second, you need to take that display orientation into account when controlling the aspect ratio of the SurfaceView / TextureView that you are using. The CameraPreview activity from ApiDemos has its own Preview ViewGroup that handles the aspect ratio, and there you need to reverse the aspect ratio for use in portrait:

if (displayOrientation == 90
        || displayOrientation == 270) {
      previewWidth=mPreviewSize.height;
      previewHeight=mPreviewSize.width;
    }
    else {
      previewWidth=mPreviewSize.width;
      previewHeight=mPreviewSize.height;
    }

where displayOrientation is that same value (90 and 270 being portrait and reverse-portrait respectively, and note that I haven't tried getting reverse-portrait or reverse-landscape to work, so there may be more tweaking required).

Third - you must start the preview before calling setPictureSize() on the Camera.Parameters . Otherwise, it's as if the aspect ratio of the picture is applied to the preview frames, screwing things up.

Camera.Parameters parameters=camera.getParameters();
Camera.Size pictureSize=getHost().getPictureSize(parameters);

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

camera.setParameters(parameters);
camera.startPreview();

parameters=camera.getParameters();
parameters.setPictureSize(pictureSize.width, pictureSize.height);
parameters.setPictureFormat(ImageFormat.JPEG);
camera.setParameters(parameters);

I fixed this using the Google's camera app. It gets the phone's orientation by using a sensor and then sets the EXIF tag appropriately. The JPEG which comes out of the camera is not oriented automatically.

Also, the camera preview works properly only in the landscape mode. If you need your activity layout to be oriented in portrait, you will have to do it manually using the value from the orientation sensor.

I'd recommend checking the photo's exif data and looking particularly for

ExifInterface exif = new ExifInterface(SourceFileName);   //API Level 5
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);

Leave comment and Let me know if this helps you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM