2011-09-02 77 views
46

我有這樣的代碼:Android獲取相機位圖的方位?和轉回-90度

//choosed a picture 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 

    if (resultCode == RESULT_OK) { 
     if (requestCode == ImageHelper.SELECT_PICTURE) { 

      String picture   = ""; 

      Uri selectedImageUri  = data.getData(); 
      //OI FILE Manager 
      String filemanagerstring = selectedImageUri.getPath(); 
      //MEDIA GALLERY 
      String selectedImagePath = ImageHelper.getPath(mycontext, selectedImageUri); 

      picture=(selectedImagePath!=null)?selectedImagePath:filemanagerstring; 

...

這只是一個圖片選擇器,從畫廊。這是很好的,但是當我在imageview上打開這張照片時,圖像在相機上拍攝「肖像模式」時看起來不錯,但是相機拍攝了「景觀模式」的圖像以-90度打開。

我該如何旋轉這些圖片?

Bitmap output  = Bitmap.createBitmap(newwidth, newheight, Config.ARGB_8888); 
    Canvas canvas  = new Canvas(output); 

我想這:

Log.e("w h", bitmap.getWidth()+" "+bitmap.getHeight()); 
if (bitmap.getWidth()<bitmap.getHeight()) canvas.rotate(-90); 

,但是這是不工作,所有的圖像尺寸是:* 2560 1920像素(縱向和橫向模式全)

我能做些什麼旋轉LANDSCAPE圖片?

感謝萊斯利

回答

178

如果照片是用數字照相機或智能電話,旋轉通常存儲在照片的Exif數據,作爲圖像文件的一部分。您可以使用Android ExifInterface閱讀圖片的Exif元數據。

首先,創建ExifInterface

ExifInterface exif = new ExifInterface(uri.getPath()); 

接下來,找到當前旋轉:

int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 

轉換EXIF旋轉度:

int rotationInDegrees = exifToDegrees(rotation); 

其中

private static int exifToDegrees(int exifOrientation) {   
    if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; } 
    else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) { return 180; } 
    else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) { return 270; }    
    return 0;  
} 

然後使用圖像的實際旋轉作爲參考點,使用Matrix旋轉圖像。

Matrix matrix = new Matrix(); 
if (rotation != 0f) {matrix.preRotate(rotationInDegrees);} 

創建與Bitmap.createBitmap方法採取Matrix作爲參數的新旋轉的圖像:

Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) 

其中Matrix m擁有新的輪換:

Bitmap adjustedBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, width, height, matrix, true); 

看到這些教程有用的源代碼示例:

+0

很好的答案,但你如何在矩陣中使用int「旋轉」? – Cole

+0

@科爾 - 我已經編輯了我的答案,包括如何在矩陣中使用旋轉變量的解釋。 –

+2

謝謝你這樣徹底的回答! – Cole

0

最後回答在技術上是完美的,但我努力創建一個系統來管理圖片,旋轉,調整大小,緩存並加載到ImageViews,我可以告訴它是一個地獄。即使完成所有操作,崩潰有時會在某些設備中導致OutOfMemory。

我的觀點是不要重新發明輪子,它有一個完美的設計。 Google本身鼓勵您使用Glide。它工作在一條線上,超級簡單易用,尺寸和功能號碼都很輕巧,它管理EXIF默認爲,它使用內存就像一個魅力..它簡直是黑魔法編碼;)

我是不知道是否Picasso還管理EXIF,但有一個快速的介紹他們兩個:

https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en

我的建議是:不要浪費你的時間和使用它們。你可以解決你的問題在一條線:

Glide.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView); 
+0

是的,但問題是,如果你已經解碼/下采樣舉個例子,或者使用jpeg格式進行壓縮。 EXIF未保留,所以您需要將屬性重置爲新文件。 – ngatirauks