Reputation: 533
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.
Upvotes: 0
Views: 9772
Reputation: 1700
Camera.Parameters params= mCamera.getParameters();
params.set("rotation", 90);
mCamera.setParameters(params);
Upvotes: 5
Reputation: 1133
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);
Upvotes: 1
Reputation: 1133
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.
Upvotes: 0