4

在我的Android應用程序中,我正在從設備庫中加載圖像。在那裏,我面臨圖像方向的問題。當我從圖庫中加載大分辨率圖像時,它們會自動旋轉,然後顯示在我的視圖中。我嘗試過關於這個問題的各種解決方案,但無法得到適當的解我提到了getOrientation()this的鏈接。我已嘗試這兩種解決方案,但無法獲得理想的結果。ExifInterface返回正確的數據,但它們也沒有幫助,因爲圖像旋轉是因爲它們的分辨率較高,而不是相機方向。請幫我解決這個問題。圖片自畫廊自動旋轉 - Android

謝謝。

回答

24

製作一個名爲類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); 

謝謝!

+0

我在我這樣的活動中調用它:'Bitmap b1 = BitmapFactory.decodeFile(imagePath); b = ExifUtils.rotateBitmap(imagePath,b1);'但不工作。我認爲你的解決方案是正確的,因爲在'ExifUtil'類中它執行'case 6',這是正確的。我不知道爲什麼不工作。 – zanky

+0

雅..它正確... – Piyush

+0

它顯示風景圖像。 – zanky