当前位置: 首页 > 知识库问答 >
问题:

使用自定义相机拍摄的图像方向错误

尉迟浩思
2023-03-14

我创建了自定义相机活动,但拍摄的图像方向错误。当我在纵向模式下拍摄图像并将其旋转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;
    }

共有1个答案

锺宜
2023-03-14

终于找到了解决办法。使用方向传感器检查方向,根据角度找到角度,并使用该角度旋转生成的图像。

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;

    }
 类似资料:
  • 所以我遇到了一个问题,前面在我提问的问题中提到过:将图像(ACTION_image_CAPTURE)上载到Firebase存储 我对这个问题进行了更多的搜索,并应用了Android Studio文档:https://developer.android.com/training/camera/photobasics.html#TaskPhotoView 所以,在您阅读代码之前,我基本上想说一下需要什

  • 在我的应用程序中,用户从相机捕获图像或从图库中选择图像,然后将其转换为pdf并上载到服务器,现在我的问题是,从相机捕获的图像在某些设备上旋转,我有代码尝试解决此问题,但它不起作用 任何建议或问题在哪里,没有错误代码或任何东西

  • 我已经建立了一个自定义的相机应用程序。面对屏幕方向的问题,我不希望在方向改变时重新创建活动。请用完整的解决方案帮助我。 在预览类中的surfaceChanged方法内获取空指针异常。 获取以下行中的空指针异常: 任何帮助将不胜感激。 以下是错误日志: 12-23 16:07:34.962 8845-8845/com。清晰摄像机E/AndroidRuntime﹕ 致命异常:主进程:com。清晰摄像头

  • 浏览使用数码(数字)相机拍摄的图像 使用支持Memory Stick™的数码(数字)相机时,只要将相机的Memory Stick™直接插入PSP™主机,即能显示图像。拍摄后的图像会显示于[相机图像]文件夹中。 提示 Memory Stick™内的[DCIM]文件夹会转换为[相机图像]显示。一般的数码(数字)相机都会自动新建[DCIM]文件夹。

  • 我正在开发一个应用程序,在这个应用程序中,我以纵向方向拍摄照片,问题是当我稍后检索图像时,它是横向方向的(图片已逆时针旋转90度)。我曾经在课下使用过,但这里每次都是0(零)。所以,我不知道怎么解决它。

  • 问题内容: 在Swift 2.3中,我使用以下代码在自定义相机中拍照: 但是他的话: 显示此错误: 类型“ AVCapturePhotoOutput”的值没有成员“ captureStillImageAsynchronouslyFromConnection” 我尝试解决问题,但是我总是收到越来越多的错误,所以这就是我发布原始代码的原因。 有人知道如何使我的代码再次起作用吗? 谢谢。 问题答案: 多