Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
379 views
in Technique[技术] by (71.8m points)

android - Rotating a Camera SurfaceView to portrait

I have looked up a few posts on changing the orientation of the camera with a surface view, but I have taken my code from the examples at:

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html

The function that provides the dimensions looks like this...

    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;
        if (sizes == null) return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

My problem is that when I change the orientation of the device, the preview picture stays landscape. I tried setting the orientation of the camera but this resulted in very strange results. Does anyone know what I need to change to have this rotate properly?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The code to correctly adjust the camera preview orientation is a bit complex, since it has to take into account

  1. The relative orientation of the sensor and the device's 'natural' orientation (which is portrait for phones, landscape for tablets, typically)
  2. The current UI orientation of the device (portrait, landscape or the reverse of each)
  3. Whether the camera in question is the front or the back camera (since the front preview stream is mirrored horizontally)

The documentation for Camera.setDisplayOrientation has sample code on how to deal with this correctly. I'm reproducing it here:

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

Call this after your UI has been drawn (onSurfaceChanged would work as an indicator) or the device UI rotates (onConfigurationChanged would work as an indicator).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...