3

I am using this code:

https://github.com/commonsguy/cw-advandroid/blob/master/Camera/Picture/src/com/commonsware/android/picture/PictureDemo.java

where in Manifest, Activity Orientation is set to Landscape.

So, its like allowing user to take picture only in Landscape mode, and if the picture is taking by holding the device in portrait mode, the image saved is like this:

enter image description here

a 90 degree rotated image.

After searching for a solution, I found this:

Android - Camera preview is sideways

where the solution is:

in surfaceChanged() check for

Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
display.getRotation();

and change the Camera's displayOrientation accordingly.

camera.setDisplayOrientation(90);

But no matter how many times I rotate the device, surfaceChanged() never gets called.

I even tried removing orientation="Landscape" in the Manifest.xml, but then the preview itself is shown sideways(may be because default android.view.SurfaceView is supposed to be in Landscape mode?).

Community
  • 1
  • 1
Archie.bpgc
  • 22,633
  • 38
  • 142
  • 219
  • check this link, it may be useful for you. http://stackoverflow.com/questions/5157984/android-camera-surfaceview-orientation – Hiren Dabhi Apr 19 '13 at 07:40
  • Well, there *are* reasons why I'm no longer covering this code in the book... :-) I left it in the repo for historical reasons, but there are certainly issues with it. FWIW, I do plan on revisiting this topic in the coming months, with an eye towards ironing out this sort of problem, and I have made a note to investigate this then. However, right now, I have no particular advice for you -- my apologies. – CommonsWare Apr 19 '13 at 11:18

2 Answers2

4

Try this.

public void surfaceCreated(SurfaceHolder holder) {
    try {
        camera = Camera.open();
        camParam = camera.getParameters();
        Camera.Parameters params = camera.getParameters();
        String currentversion = android.os.Build.VERSION.SDK;
        Log.d("System out", "currentVersion " + currentversion);
        int currentInt = android.os.Build.VERSION.SDK_INT;
        Log.d("System out", "currentVersion " + currentInt);

        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            if (currentInt != 7) {
                camera.setDisplayOrientation(90);
            } else {
                Log.d("System out", "Portrait " + currentInt);

                params.setRotation(90);

                /*
                 * params.set("orientation", "portrait");
                 * params.set("rotation",90);
                 */
                camera.setParameters(params);
            }
        }
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            // camera.setDisplayOrientation(0);
            if (currentInt != 7) {
                camera.setDisplayOrientation(0);
            } else {
                Log.d("System out", "Landscape " + currentInt);
                params.set("orientation", "landscape");
                params.set("rotation", 90);
                camera.setParameters(params);
            }
        }
        camera.setPreviewDisplay(holder);
        camera.startPreview();
    } catch (IOException e) {
        Log.d("CAMERA", e.getMessage());
    }
}
Hiren Dabhi
  • 3,555
  • 5
  • 32
  • 58
  • 1
    I think this will work only for the first time because its written in `surfaceCreated()`. Later(once the preview is on) if user changes the device orientation, nothing happens and the picture taken will be sideways again. – Archie.bpgc Apr 19 '13 at 07:19
0

Since you've forced your application to be landscape, your application's configuration won't change when you rotate the device, and as a result, your UI won't get redrawn. So you'll never see a surfaceCreated/Changed callback because of it.

In any case, your issue isn't with preview, it's with the captured pictures.

The camera API doesn't automatically know which way is down; it needs you to tell it how you want your images rotated by using the Camera.Parameters setRotation method. There are several coordinate systems in play here (the orientation of the camera sensor relative to your device; the orientation of your UI relative to the device; and the orientation of the device relative to the world) which have to be done correctly.

So I highly recommend you use the code provided in the setRotation documentation, and inherit from the OrientationEventListener, implementing the listener as follows:

 public void onOrientationChanged(int orientation) {
   if (orientation == ORIENTATION_UNKNOWN) return;
   android.hardware.Camera.CameraInfo info =
        new android.hardware.Camera.CameraInfo();
   android.hardware.Camera.getCameraInfo(cameraId, info);
   orientation = (orientation + 45) / 90 * 90;
   int rotation = 0;
   if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
       rotation = (info.orientation - orientation + 360) % 360;
   } else {  // back-facing camera
     rotation = (info.orientation + orientation) % 360;
   }
   mParameters.setRotation(rotation);
 }

This will update your camera's still picture orientation correctly so that 'up' is always up, whether your app is landscape or portrait, or your device is a tablet or a phone.

Eddy Talvala
  • 15,449
  • 2
  • 37
  • 42