【问题标题】:Image is getting rotated when clicked from camera only in Samasung device仅在三星设备中从相机单击时图像会旋转
【发布时间】:2016-12-06 11:59:30
【问题描述】:

在我的应用程序中,当在纵向模式下从相机中单击图像时,图像会旋转,这仅适用于三星设备,其余设备工作正常。在研究堆栈溢出后,我实现了以下代码:

ExifInterface ei = new ExifInterface(imgFile.getPath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);

switch (orientation) {
case ExifInterface.ORIENTATION_UNDEFINED:
mBitmap = rotateImage(bitmap, 90);
break;
}

这段代码帮助我解决了三星中的这个问题,但是现在当从相机点击图像时,由于这段代码,它在其他设备中被旋转。

请告诉我如何解决此问题。

【问题讨论】:

  • 就文档而言:getAttributeInt "返回指定标签的整数值。如果图像文件中没有这样的标签或该值无法解析为整数,则返回 defaultValue。" , 这意味着标签未定义,并且返回 ExifInterface.ORIENTATION_UNDEFINED (0),或者您的开关未处理 ORIENTATION_(something) 情况。添加一个默认子句,并记录返回的orientation
  • 好的,非常感谢..会这样做..我在切换之前检查了方向的值,它说 0..
  • 还要注意这个“问题”是旧的,since 2012 知道三星不会正确保存 Exif 数据。 Even the Exif standard 存在导致不兼容情况的问题。由于三星不支持 Exif 界面,您可以自己编辑该设置(如果您要求相机意图,请使用设备方向)或检查位图高度/宽度,并相应地翻转图像。
  • 好的好的..非常感谢

标签: android android-camera image-rotation


【解决方案1】:

使用下面的类

 String path="path of your image";

 imageview.setImageBitmap(ExifUtil.rotateBitmap(path, BitmapFactory.decodeFile(path)));

ExifUtil.java

public class ExifUtil {
    /**
     * @see http://sylvana.net/jpegcrop/exif_orientation.html
     */
    public static Bitmap rotateBitmap(String src, Bitmap bitmap) {
        try {
            int orientation = getExifOrientation(src);

            if (orientation == 1) {
                return bitmap;
            }

            Matrix matrix = new Matrix();
            switch (orientation) {
            case 2:
                matrix.setScale(-1, 1);
                break;
            case 3:
                matrix.setRotate(180);
                break;
            case 4:
                matrix.setRotate(180);
                matrix.postScale(-1, 1);
                break;
            case 5:
                matrix.setRotate(90);
                matrix.postScale(-1, 1);
                break;
            case 6:
                matrix.setRotate(90);
                break;
            case 7:
                matrix.setRotate(-90);
                matrix.postScale(-1, 1);
                break;
            case 8:
                matrix.setRotate(-90);
                break;
            default:
                return bitmap;
            }

            try {
                Bitmap oriented = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                bitmap.recycle();
                return oriented;
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
                return bitmap;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } 

        return bitmap;
    }

    private static int getExifOrientation(String src) throws IOException {
        int orientation = 1;

        try {
            /**
             * if your are targeting only api level >= 5
             * ExifInterface exif = new ExifInterface(src);
             * orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
             */
            if (Build.VERSION.SDK_INT >= 5) {
                Class<?> exifClass = Class.forName("android.media.ExifInterface");
                Constructor<?> exifConstructor = exifClass.getConstructor(new Class[] { String.class });
                Object exifInstance = exifConstructor.newInstance(new Object[] { src });
                Method getAttributeInt = exifClass.getMethod("getAttributeInt", new Class[] { String.class, int.class });
                Field tagOrientationField = exifClass.getField("TAG_ORIENTATION");
                String tagOrientation = (String) tagOrientationField.get(null);
                orientation = (Integer) getAttributeInt.invoke(exifInstance, new Object[] { tagOrientation, 1});
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        return orientation;
    }
}

【讨论】:

  • 你的问题解决了吗?
【解决方案2】:

通过返回度来转换位图,

try {
       ExifInterface exif = new ExifInterface(imgPath);  
        String rotationAmount = exif
                .getAttribute(ExifInterface.TAG_ORIENTATION);
        if (!TextUtils.isEmpty(rotationAmount)) {
            int rotationParam = Integer.parseInt(rotationAmount);
            switch (rotationParam) {
            case ExifInterface.ORIENTATION_NORMAL:
                return 0;
            case ExifInterface.ORIENTATION_ROTATE_90:
                return 90;
            case ExifInterface.ORIENTATION_ROTATE_180:
                return 180;
            case ExifInterface.ORIENTATION_ROTATE_270:
                return 270;
            default:
                return 0;
            }
        } else {
            return 0;
        }
    } catch (Exception ex) {
        return 0;
    }

【讨论】:

  • 我总是将旋转量设为 0.. 所以它总是在旋转
  • 查看更新代码,根据图片获取旋转,先获取图片位置,再找到位图旋转需求。
【解决方案3】:

如果您确信这只是三星设备的问题,您可以检查设备制造商并将其添加到您的 if(...) 条件中。 This 库可以提供很大帮助。

还可以查看 Jared Rummler 对this 问题的回答:

但是,如果这是特定于设备的问题,它也可能出现在其他设备上,或者最终可能在较新的三星设备操作系统更新中得到纠正。好好检查一下。

【讨论】:

    猜你喜欢
    • 2018-04-25
    • 2017-03-08
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 2022-09-28
    • 1970-01-01
    相关资源
    最近更新 更多