来自图库的图像会自动旋转 - Android

时间:2013-12-17 12:33:08

标签: android bitmap android-imageview bitmapfactory android-bitmap

在我的Android应用程序中,我正在从设备库加载图像。在那,我面临着关于图像方向的问题。当我从图库中加载大分辨率图像时,它们会自动旋转,然后在我的视图中显示。我尝试了有关此问题的各种解决方案但无法得到正确的解决方案我提到了getOrientation()this个链接。我已尝试过两种解决方案,但无法得到理想的结果。ExifInterface返回正确的数据,但随后由于分辨率较大而不是因为相机方向而导致图像旋转,因此无效。请帮我解决这个问题。

谢谢。

2 个答案:

答案 0 :(得分:25)

创建一个名为 ExifUtils

的类
public class ExifUtils {
/**
 * @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;
}

现在您可以通过以下方式在“活动”中调用它:

  ExifUtils.rotateBitmap("your Image path here", "your bitmap object here");

修改

 public void decodeFile(String filePath) {

    // Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, o);

    // The new size we want to scale to
    final int REQUIRED_SIZE = 1024;

    // Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;
    while (true) {
        if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
            break;
        width_tmp /= 2;
        height_tmp /= 2;
        scale *= 2;
    }

    // Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    Bitmap b1 = BitmapFactory.decodeFile(filePath, o2);
    Bitmap b= ExifUtils.rotateBitmap(filePath, b1);

    // image.setImageBitmap(bitmap);
}

现在调用此方法

  decodeFile(imagepath);

谢谢!

答案 1 :(得分:0)

这很好;

public class ExifUtils {

public static Bitmap getRotatedBitmap(Context context, Uri uri) {
    try {
        Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);
        float width = (float) bitmap.getWidth();
        float height = (float) bitmap.getHeight();
        float max = Math.max(width / 1280.0f, height / 1280.0f);
        if (max > 1.0f) {
            bitmap = Bitmap.createScaledBitmap(bitmap, (int) (width / max), (int) (height / max), false);
        }
        Bitmap rotateBitmap = rotateBitmap(bitmap,
                new ExifInterface(context.getContentResolver().openInputStream(uri))
                        .getAttributeInt(ExifInterface.TAG_ORIENTATION, 1));
        if (rotateBitmap != bitmap) {
            bitmap.recycle();
        }
        return rotateBitmap;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

private static Bitmap rotateBitmap(Bitmap bitmap, int i) {
    Matrix matrix = new Matrix();
    switch (i) {
        case 2:
            matrix.setScale(-1.0f, 1.0f);
            break;
        case 3:
            matrix.setRotate(180.0f);
            break;
        case 4:
            matrix.setRotate(180.0f);
            matrix.postScale(-1.0f, 1.0f);
            break;
        case 5:
            matrix.setRotate(90.0f);
            matrix.postScale(-1.0f, 1.0f);
            break;
        case 6:
            matrix.setRotate(90.0f);
            break;
        case 7:
            matrix.setRotate(-90.0f);
            matrix.postScale(-1.0f, 1.0f);
            break;
        case 8:
            matrix.setRotate(-90.0f);
            break;
        default:
            return bitmap;
    }
    try {
        Bitmap createBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
        bitmap.recycle();
        return createBitmap;
    } catch (OutOfMemoryError e) {
        e.printStackTrace();
        return null;
    }
  }
}