Rotating a Camera SurfaceView to portrait

前端 未结 7 1000
日久生厌
日久生厌 2020-12-14 04:37

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.c

相关标签:
7条回答
  • 2020-12-14 04:54

    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).

    0 讨论(0)
  • 2020-12-14 04:55

    Well i Do this!

    I have solved this issue in in this way in surfaceCreated() method

     public void surfaceCreated(SurfaceHolder holder) {
        try {
    
            camera = Camera.open();
        } catch (RuntimeException e) {
            System.err.println(e);
            return;
        }
        Camera.Parameters param;
        param = camera.getParameters();
        if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
        {
            param.set("orientation", "portrait");
            setCameraDisplayOrientation(this,1,camera);
        }
        camera.setParameters(param);
    
        try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
        } catch (Exception e) {
            System.err.println(e);
            return;
        }
    }
    

    add this method below

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

    3: Make sure you have added camera permiison to support for nougat in a activity before this activity calling dont call permission for camera in this activity because surfacecreated call as the activity created, and your permission will be pending to open camera

    0 讨论(0)
  • 2020-12-14 04:58

    I was able to solve the rotation problem by putting the following code in onSurfaceChanged():

        if (mHolder.getSurface() == null) {
            // preview surface does not exist
            return;
        }
    
        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e) {
            // ignore: tried to stop a non-existent preview
        }
    
        // make any resize, rotate or reformatting changes here
        if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
    
            mCamera.setDisplayOrientation(90);
    
        } else {
    
            mCamera.setDisplayOrientation(0);
    
        }
        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
    
        } catch (Exception e) {
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    

    BUT this created another problem, or better put, didn't solve a problem-while oriented correctly, the preview image still only took up the same amount of space that the landscape view did. I ended up just giving up and forcing landscape orientation with:

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    

    in onCreate() and designed my layout for landscape. Best of luck, and I hope someone has an answer for this secondary problem!

    0 讨论(0)
  • 2020-12-14 04:58

    I solved this issue by adding:

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    

    To the onCreate event.

    0 讨论(0)
  • 2020-12-14 04:59

    Try this out, but I tried in Samsung Galaxy Tab

    public void surfaceCreated(SurfaceHolder holder)
    {
       // The Surface has been created, acquire the camera and tell it where to draw.
       mCamera = Camera.open();
    
       Parameters params = mCamera.getParameters();
    
       if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
       {
        params.set("orientation", "portrait");
        mCamera.setDisplayOrientation(90);
       }
    
        try
          {
          mCamera.setPreviewDisplay(holder);
          }
          catch (IOException exception)
          {
            mCamera.release();
            mCamera = null;
          }
    
    }
    
    0 讨论(0)
  • 2020-12-14 05:16

    Only add this

    mCamera.setDisplayOrientation(90);
    
    0 讨论(0)
提交回复
热议问题