2011-09-02 11 views
46

mam ten kod:Android uzyskać Orientacja kamery Bitmap? I obrócić z powrotem -90 stopni

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

...

to tylko Chooser obraz z galerii. to jest miłe, ale kiedy otwieram to zdjęcie na obrazie, zdjęcia, kiedy wykonano "TRYB PORTRETOWY" z aparatem, wyglądają ładnie, ale obrazy, które zrobiły "TRYB KRAJOBRAZU" z aparatem, otwierają się w -90 stopniach.

Jak mogę obrócić te zdjęcia z powrotem?

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

próbowałem to:

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

ale to nie działa, wszystkie rozmiar obrazu to: * 2560 1920 pikseli (portret i trybie poziomym wszystkie)

Co mogę zrobić, aby odwrócić obrazy LANDSCAPE?

dzięki Leslie

Odpowiedz

178

Jeśli zdjęcie jest zrobione aparatem cyfrowym lub smartphone, rotacja jest często przechowywane w Exif danych na zdjęciu, tak jak część pliku obrazu. Możesz odczytać metadane Exif obrazu za pomocą Androida ExifInterface.

Najpierw utwórz ExifInterface:

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

Następnie znaleźć aktualny obrotów:

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

Convert exif obrót na stopniach:

int rotationInDegrees = exifToDegrees(rotation); 

gdzie

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

Następnie użyj rzeczywistego obrotu obrazu jako punktu odniesienia, aby obrócić zdjęcie za pomocą Matrix.

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

utworzyć nową obrócony obraz za pomocą metody Bitmap.createBitmap które wymagają Matrix jako parametr:

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

gdzie Matrix m posiada nową obrotów:

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

zobaczyć te tutoriale dla użyteczne przykłady kodu źródłowego:

+0

Świetna odpowiedź, ale w jaki sposób wykorzystujesz int "rotacja" w Matrixie? – Cole

+0

@ Cole - Edytowałem swoją odpowiedź, aby objaśnić, jak używać zmiennej rotacyjnej z macierzą. –

+2

Dzięki za tak dokładną odpowiedź! – Cole

0

Ostatnia odpowiedź była technicznie doskonała, ale bardzo się starałem stworzyć system do zarządzania zdjęciami, obracania, zmiany rozmiaru, buforowania i ładowania do ImageViews i mogę powiedzieć, że to piekło.Nawet gdy wszystko zostało zrobione, awarie czasami powodują OutOfMemory w niektórych urządzeniach.

Chodzi mi o to, że nie wymyślam na nowo koła, ma on doskonały design. Sam Google zachęca do korzystania z usługi Glide. Działa w jednym wierszu, super łatwy w użyciu, niewielki rozmiar i numer funkcji, zarządza EXIF ​​domyślnie, i używa pamięci jak uroku. Jest po prostu zakodowany czarną magią;)

Jestem nie wiem, czy Picasso zarządza również EXIF, ale jest szybki wstęp do obu z nich:

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

Moja rada: nie trać czasu i korzystania z nich. Możesz rozwiązać swój problem w jednym wierszu:

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

Tak, ale problem polega na tym, że dekodowanie/zmniejszanie próbkowania trochę na przykład lub skompresowane przy użyciu formatu jpeg. Format EXIF ​​nie jest zachowywany, dlatego konieczne jest zresetowanie atrybutów do nowego pliku. – ngatirauks

Powiązane problemy