Android Camera setDisplayOrientation does not work

后端 未结 4 1074
春和景丽
春和景丽 2020-12-17 01:07

i am working camera project in android.my problem is camera setDisplayOrientation method is not working and my camera preview on surface always landscape.i want

相关标签:
4条回答
  • 2020-12-17 01:22

    Finally i got solution and find camera preview surface view following code:

    import java.io.IOException;
    import java.util.List;
    import android.app.Activity;
    import android.content.Context;
    import android.content.res.Configuration;
    import android.hardware.Camera;
    import android.os.Build;
    import android.util.Log;
    import android.view.Display;
    import android.view.Surface;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    
    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
        private SurfaceHolder mHolder;
        private Camera mCamera;
    
        private static boolean DEBUGGING = true;
        private static final String LOG_TAG = "CameraPreviewSample";
        private static final String CAMERA_PARAM_ORIENTATION = "orientation";
        private static final String CAMERA_PARAM_LANDSCAPE = "landscape";
        private static final String CAMERA_PARAM_PORTRAIT = "portrait";
        protected Activity mActivity;
    
        protected List<Camera.Size> mPreviewSizeList;
        protected List<Camera.Size> mPictureSizeList;
        protected Camera.Size mPreviewSize;
        protected Camera.Size mPictureSize;
    
    
        public CameraPreview(Context context, Camera camera) {
            super(context);
    
            mActivity=(Activity)context;
            mCamera = camera;
    
            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
            // deprecated setting, but required on Android versions prior to 3.0
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    
    
        }
    
        public void surfaceCreated(SurfaceHolder holder) {
            // The Surface has been created, now tell the camera where to draw the preview.
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d("CameraView", "Error setting camera preview: " + e.getMessage());
            }
        }
    
        public void surfaceDestroyed(SurfaceHolder holder) {
            // empty. Take care of releasing the Camera preview in your activity.
        }
    
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            // If your preview can change or rotate, take care of those events here.
            // Make sure to stop the preview before resizing or reformatting it.
    
            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
            }
    
            // set preview size and make any resize, rotate or
            // reformatting changes here
    
            // start preview with new settings
            try {
                Camera.Parameters cameraParams = mCamera.getParameters();
                boolean portrait = isPortrait();
                configureCameraParameters(cameraParams, portrait);
    
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();
    
            } catch (Exception e){
                Log.d("CameraView", "Error starting camera preview: " + e.getMessage());
            }
        }
    
        public void onPause() {
            mCamera.release();
            mCamera = null;
        }
    
    
        protected void configureCameraParameters(Camera.Parameters cameraParams, boolean portrait) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { // for 2.1 and before
                if (portrait) {
                    cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_PORTRAIT);
                } else {
                    cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE);
                }
            } else { // for 2.2 and later
                int angle;
                Display display = mActivity.getWindowManager().getDefaultDisplay();
                switch (display.getRotation()) {
                    case Surface.ROTATION_0: // This is display orientation
                        angle = 90; // This is camera orientation
                        break;
                    case Surface.ROTATION_90:
                        angle = 0;
                        break;
                    case Surface.ROTATION_180:
                        angle = 270;
                        break;
                    case Surface.ROTATION_270:
                        angle = 180;
                        break;
                    default:
                        angle = 90;
                        break;
                }
                Log.v(LOG_TAG, "angle: " + angle);
                mCamera.setDisplayOrientation(angle);
            }
    
            cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
            cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height);
            if (DEBUGGING) {
                Log.v(LOG_TAG, "Preview Actual Size - w: " + mPreviewSize.width + ", h: " + mPreviewSize.height);
                Log.v(LOG_TAG, "Picture Actual Size - w: " + mPictureSize.width + ", h: " + mPictureSize.height);
            }
    
            mCamera.setParameters(cameraParams);
        }
    
    
        public boolean isPortrait() {
            return (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
        }
    }
    

    It's need minimum sdk 2.3 or higher

    0 讨论(0)
  • Also, check if the "Auto-rotate Screen" option is checked in the phone Settings (Settings > Dislay or Screen - depends on the android version).

    It took me quite a while till a figured it out. If it's not checked, the orientation of the camera in the app may be ignored.

    0 讨论(0)
  • 2020-12-17 01:36

    if you want to rotate the preview output, try this:

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
        {            
            if (isPreviewRunning)
            {
                mCamera.stopPreview();
            }
    
            Parameters parameters = mCamera.getParameters();
            Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
    
            if(display.getRotation() == Surface.ROTATION_0)
            {
                parameters.setPreviewSize(height, width);                           
                mCamera.setDisplayOrientation(90);
            }
    
            if(display.getRotation() == Surface.ROTATION_90)
            {
                parameters.setPreviewSize(width, height);                           
            }
    
            if(display.getRotation() == Surface.ROTATION_180)
            {
                parameters.setPreviewSize(height, width);               
            }
    
            if(display.getRotation() == Surface.ROTATION_270)
            {
                parameters.setPreviewSize(width, height);
                mCamera.setDisplayOrientation(180);
            }
    
            mCamera.setParameters(parameters);
            previewCamera();                      
        }
    
    0 讨论(0)
  • 2020-12-17 01:43

    For lower API levels you could use:

    private void setCameraDisplayOrientationAPI8(){
            //Sets the camera right Orientation.
            //Special void for API 8 build.
            //This void should be called before calling camera.setParameters(cameraParameters).
            if (activeActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
            {   
                camera.setDisplayOrientation(90);
            }
            if (activeActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
            {                               
                camera.setDisplayOrientation(180);
            }
        }
    

    and just call setCameraDisplayOrientationAPI8(); on your surfaceChanged func.

    plus:

    private void setCameraDisplayOrientation() {
            //Sets the camera right Orientation.
            //IMPORTANT!! This code is available only for API Level 9 build or greater.
            if (mApiLvl<9){
                Log.d(TAG, "setCameraDisplayOrientation ERROR: This code is available only for API Level 9 build or greater.");
                return;
            }
            android.hardware.Camera.CameraInfo info =
                    new android.hardware.Camera.CameraInfo();
            android.hardware.Camera.getCameraInfo(cameraIndex, info);
            int rotation = activeActivity.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);
        }
    

    hope this helps.

    0 讨论(0)
提交回复
热议问题