3

I have implemented the Camera Preview just as it is in the ApiDemos application of Android. The thing is that I want my activity, where the Preview is shown to be locked to portrait. So I set screenOrientation to portrait in the manifest.

The 'getOptimalPreviewSize' method returns opposite values for the preview, meaning, when it's needed to return 480x720, the method returns 720x480, and I have small preview centered in my FrameLayout of the activity (which is not what I want, I want it to match the parent (yes, the layout is defined with "match_parent").

I tried:

  • setDisplayOrientation(90);
  • parameters.set("orientation", "portrait");
  • parameters.set("rotation", "90");

Nothing seems to help.

Why can't I show Preview of the Camera in portrait mode? Locked.

Thanks

user584513
  • 630
  • 11
  • 20
  • 1
    http://stackoverflow.com/questions/10660598/android-camera-preview-orientation-in-portrait-mode. Here's a link similar to your requirement. Please read the Note for the accepted answer. – Raghunandan Nov 06 '12 at 13:39

2 Answers2

2

Here is a working example of a portrait preview of camera on SurfaceView :

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surface);
    surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {

        private Camera camera;

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                camera = Camera.open();
                camera.setPreviewDisplay(holder);
                camera.setDisplayOrientation(90);
                camera.startPreview();
            } catch (IOException e) {
                Log.e(TAG, "Error", e);
            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) { 
            camera.stopPreview();
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        }
    });
}

With the following layout file:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <SurfaceView
        android:id="@+id/surface"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>
sdabet
  • 18,360
  • 11
  • 89
  • 158
  • This works fine when set the contentView like this, but what If you want to set it from XML? I think the layout width and height will screw things again :/ – user584513 Nov 06 '12 at 14:01
  • can you check if this works instead of SurfaceView you use a custom View (extends ViewGroup, just as in the samples) that implements the SurfaceHolder.Callback and lock the screen orientation by setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);? Thanks! – user584513 Nov 06 '12 at 14:46
  • Which samples ? In the official guide they use a SurfaceView: http://developer.android.com/training/camera/cameradirect.html#camera-preview – sdabet Nov 06 '12 at 14:57
  • I mean..how do you get a SurfaceHolder other than with a SurfaceView ? – sdabet Nov 06 '12 at 15:00
  • The thing is that when I use this example: http://is.gd/vyx9Rt and lock the Activity only to portrait, I get wrong Preview size (centered in the Activity, small size). When I use your example it's ok ... I just need something more complex.. – user584513 Nov 06 '12 at 15:12
-1

Try setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);

That will lock the activity to that orientation.

The following code from the Google Docs:

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);
}

Which will set the orientation of the camera and preview correctly.

Chris.Jenkins
  • 13,051
  • 4
  • 60
  • 61