【问题标题】:Captured image using custom camera is in wrong orientation使用自定义相机拍摄的图像方向错误
【发布时间】:2016-10-12 07:28:28
【问题描述】:

我创建了自定义相机活动,但捕获的图像方向错误。当我以纵向模式拍摄图像并将其旋转 90 度后。它处于原始位置,但在横向模式下以错误的方向拍摄图像。

在横向拍摄图像时相机方向。

生成的图像

在人像模式下拍摄图像时的相机方向

生成的图像

用于解决相机预览问题。

public int setPhotoOrientation(Activity activity, int cameraId) {
        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;
        // do something for phones running an SDK before lollipop
        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;
        }

        return result;
    }

检查位图方向。

private Bitmap imageOreintationValidator(Bitmap bitmap, String path) {

        ExifInterface ei;
        try {
            ei = new ExifInterface(path);
            int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                bitmap = rotateImage(bitmap, 90);
                rot++;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                bitmap = rotateImage(bitmap, 180);
                rot++;
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                bitmap = rotateImage(bitmap, 270);
                rot++;
                break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

【问题讨论】:

    标签: android image camera


    【解决方案1】:

    终于找到解决方案。使用方向传感器检查方向并根据角度找到角度并使用该角度旋转结果图像。

    public abstract class SimpleOrientationListener extends OrientationEventListener {
    
        public static final int CONFIGURATION_ORIENTATION_UNDEFINED = Configuration.ORIENTATION_UNDEFINED;
        private volatile int defaultScreenOrientation = CONFIGURATION_ORIENTATION_UNDEFINED;
        public int prevOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
        private Context ctx;
        private ReentrantLock lock = new ReentrantLock(true);
    
        public SimpleOrientationListener(Context context) {
            super(context);
            ctx = context;
        }
    
        public SimpleOrientationListener(Context context, int rate) {
            super(context, rate);
            ctx = context;
        }
    
        @Override
        public void onOrientationChanged(final int orientation) {
    
    
            int currentOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
            int angle=0;
            if (orientation >= 330 || orientation < 30) {
                currentOrientation = Surface.ROTATION_0;
                angle=90;
            } else if (orientation >= 60 && orientation < 120) {
                currentOrientation = Surface.ROTATION_90;
                angle=180;
            } else if (orientation >= 150 && orientation < 210) {
                currentOrientation = Surface.ROTATION_180;
                angle=270;
            } else if (orientation >= 240 && orientation < 300) {
                currentOrientation = Surface.ROTATION_270;
                angle=360;
            }
            getset g = new getset();
            g.setK(angle);
            if (prevOrientation != currentOrientation && orientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
                prevOrientation = currentOrientation;
                if (currentOrientation != OrientationEventListener.ORIENTATION_UNKNOWN)
                    reportOrientationChanged(currentOrientation);
            }
    
        }
    
        private void reportOrientationChanged(final int currentOrientation) {
    
            int defaultOrientation = getDeviceDefaultOrientation();
            int orthogonalOrientation = defaultOrientation == Configuration.ORIENTATION_LANDSCAPE ? Configuration.ORIENTATION_PORTRAIT
                    : Configuration.ORIENTATION_LANDSCAPE;
    
            int toReportOrientation;
    
            if (currentOrientation == Surface.ROTATION_0 || currentOrientation == Surface.ROTATION_180)
                toReportOrientation = defaultOrientation;
            else
                toReportOrientation = orthogonalOrientation;
    
            onSimpleOrientationChanged(toReportOrientation);
        }
    
        /**
         * Must determine what is default device orientation (some tablets can have default landscape). Must be initialized when device orientation is defined.
         *
         * @return value of {@link Configuration#ORIENTATION_LANDSCAPE} or {@link Configuration#ORIENTATION_PORTRAIT}
         */
        private int getDeviceDefaultOrientation() {
            if (defaultScreenOrientation == CONFIGURATION_ORIENTATION_UNDEFINED) {
                lock.lock();
                defaultScreenOrientation = initDeviceDefaultOrientation(ctx);
                lock.unlock();
            }
            return defaultScreenOrientation;
        }
    
        /**
         * Provides device default orientation
         *
         * @return value of {@link Configuration#ORIENTATION_LANDSCAPE} or {@link Configuration#ORIENTATION_PORTRAIT}
         */
        private int initDeviceDefaultOrientation(Context context) {
    
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Configuration config = context.getResources().getConfiguration();
            int rotation = windowManager.getDefaultDisplay().getRotation();
    
            boolean isLand = config.orientation == Configuration.ORIENTATION_LANDSCAPE;
            boolean isDefaultAxis = rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180;
    
            int result = CONFIGURATION_ORIENTATION_UNDEFINED;
            if ((isDefaultAxis && isLand) || (!isDefaultAxis && !isLand)) {
                result = Configuration.ORIENTATION_LANDSCAPE;
            } else {
                result = Configuration.ORIENTATION_PORTRAIT;
            }
            return result;
        }
    
        /**
         * Fires when orientation changes from landscape to portrait and vice versa.
         *
         * @param orientation value of {@link Configuration#ORIENTATION_LANDSCAPE} or {@link Configuration#ORIENTATION_PORTRAIT}
         */
        public abstract void onSimpleOrientationChanged(int orientation);
    
    }
    

    用于设置预览的相机方向。

    public static int 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;
            //int currentapiVersion = android.os.Build.VERSION.SDK_INT;
            // do something for phones running an SDK before lollipop
            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;
            }
    
            return result;
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多