【问题标题】:Image from gallery rotates automatically - Android画廊中的图像自动旋转 - Android
【发布时间】:2014-01-05 05:18:13
【问题描述】:

在我的 android 应用程序中,我正在从设备库中加载图像。在这方面,我面临着关于图像方向的问题。当我从画廊加载大分辨率图像时,它们会自动旋转然后显示在我的视图中。我尝试了有关此问题的各种解决方案,但无法获得适当的解决方案。我提到了 getOrientation()this 链接。我已经尝试了这两种解决方案,但都没有得到想要的结果。ExifInterface 返回正确的数据,但它们也没有帮助,因为图像被旋转是因为它们的高分辨率而不是因为相机方向。请帮我解决这个问题。

谢谢。

【问题讨论】:

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


    【解决方案1】:

    创建一个名为 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;
    }
    

    现在您可以通过以下方式在 Activity 中调用它:

      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);
    

    谢谢!

    【讨论】:

    • 我在我的活动中这样称呼它:Bitmap b1 = BitmapFactory.decodeFile(imagePath); b = ExifUtils.rotateBitmap(imagePath, b1); 但不起作用。我认为您的解决方案是正确的,因为在 ExifUtil 类中它执行 case 6 这是正确的。我不知道为什么不工作。
    • 这些导入在课堂上是否正确? import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import android.graphics.Bitmap; import android.graphics.Matrix; import android.os.Build;
    • 没有。我只是在写:Bitmap b1 = BitmapFactory.decodeFile(imagePath); 并在你的函数中传递b1
    • @zanky 这是我的荣幸...欢迎来到
    • 不工作,我有一个按比例缩小的图像,我只是调用 ExifUtils.rotateBitmap(picPath, smallBitmap); .. getExifOrientation 返回 0.. ?
    【解决方案2】:

    这很好用;

    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;
        }
      }
    }
    

    【讨论】:

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