I have a Motorola Defy OS Android 2.1 and I make an application with camera Preview. The problem is that the camera works fine on Samsung Galaxy S with Android 2.1, but on Motorola the camera is rotated with 90 degrees. I have tried to do this:
Parameters parameters = camera.getParameters();
parameters.setRotation(90);
but it's not working. I didn't find any solution yet.
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
camera.setDisplayOrientation(90);
lp.height = previewSurfaceHeight;
lp.width = (int) (previewSurfaceHeight / aspect);
} else {
camera.setDisplayOrientation(0);
lp.width = previewSurfaceWidth;
lp.height = (int) (previewSurfaceWidth / aspect);
}
There is official example code for this in the Android docs now (under setDisplayOrientation()):
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);
}
camera.setDisplayOrientation(int) is not exist under 2.1!
And this code may work, but fail in my milestone/droid :(
Camera.Parameters parameters = camera.getParameters();
parameters.set("orientation", "portrait");
camera.setParameters(parameters);
you can see more in http://code.google.com/p/android/issues/detail?id=1193#c42
I found this code that works in Android 1.6 and over (works for me using 2.1 and present preview in portrait mode without rotating)
public void surfaceCreated(SurfaceHolder holder){
try{
camera = Camera.open();
setDisplayOrientation(camera, 90);
camera.setPreviewDisplay(holder);
camera.startPreview();
}catch(IOException e){
Log.d("CAMERA", e.getMessage());
}
}
protected void setDisplayOrientation(Camera camera, int angle){
Method downPolymorphic;
try
{
downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class });
if (downPolymorphic != null)
downPolymorphic.invoke(camera, new Object[] { angle });
}
catch (Exception e1)
{
}
}
The activity has android:screenOrientation="portrait" on AndroidManifest.xml
http://code.google.com/p/android/issues/detail?id=1193#c42
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);
}
I think that you can not make any setting to support the API 2.2 to 2.1. The API doesn't have in your current device lib. You must change to 2.2 to support API level 8. By the way, I also try to use the API level 7:
Parameters parameters = camera.getParameters();
parameters.setRotation(90);
This function works well on the Samsung Galaxy Tab but Nexus one. The Samsung Galaxy Tab uses OS 2.2.0 and the Nexus one uses OS 2.2.1. When I try to use API level 8:
camera.setDisplayOrientation(90);
both of them work well. So I think that the API level 7 has problem when we use on Android OS 2.2.1.
Related
I want to capture a video always horizontally.
If the user rotates the phone, I want to capture the video horizontally.
I have one reference for that but I want to make it for my own with customization.
how can I implement this in a smooth way?
Try this
public static void setCameraDisplayOrientation(int phoneRotation, int cameraId, Camera camera) {
Camera.CameraInfo info = new Camera.CameraInfo();
info = Camera.getCameraInfo(cameraId, info);
int degrees = 0;
switch (phoneRotation) {
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;
} else {
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
when phoneRotation is
int phoneRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
By the way this answer originally refactored from some answer in stackoverflow.
So after a while of messing with the camera, I've finally got the actual camera orientation working with this:
private 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);
}
However, the status bar (the thing at the top with time and network info) is still in landscape.
I've already included this:
android:screenOrientation="portrait"
in my AndroidManifest.xml
Any ideas on how to fix this?
If you know what you want to set your orientation as you can use setRequestedOrientation(int requestedOrientation) in your Activity
To get the camera reference, I do this:
#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "Surface created!");
mCamera = Camera.open();
if (mCamera == null) {
// try to open front facing camera
try {
mCamera = Camera.open(0);
} catch (RuntimeException e) {
Toast.makeText(getApplicationContext(),
"No camera available!", Toast.LENGTH_LONG).show();
}
}
try {
mCamera.setPreviewDisplay(mCameraHolder);
setCameraDisplayOrientation(CameraActivity.this, 0, mCamera);
} catch (Exception e) {
e.printStackTrace();
if (mCamera != null)
mCamera.release();
mCamera = null;
}
}
Where setCameraDisplayOrientation is this (which I found on stackoverflow somewhere):
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);
}
When I take a picture with my Nexus 4, it has the right orientation. When I try it with my Nexus 7, which only has a front facing camera, it is mirrored (upside down) (was it even without this piece of code actually, so it kind of does nothing I guess.).
Is there any reliable way to get the camera orientation and to make this work? I've searched on Google and Stackoverflow but did not find anything that works so far.
This is the solution that I found worked with the nexus 7 and majority other devices I tested like HTC One M8, Lenovo Yoga, Lg G4 Nexus 4, Note 4 and the Oneplus One.
camera.setDisplayOrientation(90);
However, this solution doesn't work with the Nexus 6 which flips the preview, so if anyone has a better solution than this please share.
How to keep camera in portrait mode in all devices?
my app is above 2.2
I tried
public void setRotation(int rotation) {
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;
CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (cameraInfo.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (cameraInfo.orientation - degrees + 360) % 360;
}
mCamera.stopPreview();
mCamera.setDisplayOrientation(result);
mCamera.startPreview();
}
but samsung devices ignoring mCamera.setDisplayOrientation(90)
Edited:
devices I found ignoring this:
Galaxy y(GT-S5360)(Android 2.3.6)
Galaxy Ace(GT-S5830)(Android 2.6.3)
but Galaxy S2 and other higher phones working well.
You can try
public int getCorrectCameraOrientation(CameraInfo info, Camera camera) {
int rotation = context.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;
}else{
result = (info.orientation – degrees + 360) % 360;
}
return result;
}
Use this method as
mCamera.setDisplayOrientation(getCorrectCameraOrientation(mCameraInfo, mCamera));
This is not enough for rotation handling, you need to do below step also
mCamera.getParameters().setRotation(getCorrectCameraOrientation(mCameraInfo, mCamera));
This question already has answers here:
Android Camera in Portrait on SurfaceView
(6 answers)
Closed 7 years ago.
Is it possible to open the Camera Intent in android in only portrait mode, that is even if the user flipped the device, the camera will still be in portrait mode,
I tried the following answer: Force Portrait Mode but didn't work, Thanks
Try it -
private 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);
}
private void initCamera() {
if(mCamera == null) {
mCamera = Camera.open();
setCameraDisplayOrientation(activity, CameraInfo.CAMERA_FACING_BACK, mCamera);
mCamera.unlock();
}
}