Kiedy ładuję obraz z galerii multimediów do mapy bitowej, wszystko działa dobrze, z wyjątkiem tego, że zdjęcia zrobione aparatem, trzymając telefon w pionie, są obracane tak, że zawsze otrzymuję obraz poziomy, nawet jeśli wygląda pionowo w Galeria. Dlaczego tak jest i jak mogę go poprawnie załadować?
138
Odpowiedzi:
Czy spojrzałeś na dane EXIF obrazów? Może znać orientację aparatu w momencie wykonania zdjęcia.
źródło
A więc jako przykład ...
Najpierw musisz utworzyć ExifInterface:
Następnie możesz pobrać orientację obrazu:
Oto, co oznaczają wartości orientacji: http://sylvana.net/jpegcrop/exif_orientation.html
Zatem najważniejsze wartości to 3, 6 i 8. Jeśli na przykład orientacja to
ExifInterface.ORIENTATION_ROTATE_90
(czyli 6), możesz obrócić obraz w następujący sposób:To tylko szybki przykład. Jestem pewien, że istnieją inne sposoby wykonywania rzeczywistej rotacji. Ale znajdziesz je również w StackOverflow.
źródło
OutOfMemoryError
takie podejście, ponieważ jednocześnie przechowujesz w pamięci dwie mapy bitowe.To jest pełne rozwiązanie (znalezione w przykładzie Hackbook z Facebook SDK). Ma tę zaletę, że nie potrzebuje dostępu do samego pliku. Jest to niezwykle przydatne, jeśli ładujesz obraz z programu do rozpoznawania treści (np. Jeśli Twoja aplikacja reaguje na zamiar udostępniania zdjęcia).
Następnie możesz uzyskać obróconą mapę bitową w następujący sposób. Ten kod skaluje również obraz (niestety niestety) do MAX_IMAGE_DIMENSION. W przeciwnym razie może zabraknąć pamięci.
źródło
ExifInterface exif = new ExifInterface(photoUri.getPath());
, a następnieexif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1)
, aby uzyskać orientację (npORIENTATION_ROTATE_90
,ORIENTATION_ROTATE_180
)Rozwiązałem to w moim przypadku za pomocą tego kodu, korzystając z pomocy tego postu:
Mam nadzieję, że to oszczędza komuś czas!
źródło
Użyj narzędzia, aby wykonać ciężkie podnoszenie.
9re stworzyło proste narzędzie do obsługi ciężkich zadań związanych z przetwarzaniem danych EXIF i obracaniem obrazów do ich prawidłowej orientacji.
Możesz znaleźć kod narzędzia tutaj: https://gist.github.com/9re/1990019
Po prostu pobierz to, dodaj do
src
katalogu swojego projektu i użyj,ExifUtil.rotateBitmap()
aby uzyskać prawidłową orientację, na przykład:źródło
to dlatego, że galeria poprawnie wyświetla obrócone obrazy, ale nie wygląda na ImageView tutaj:
i potrzebujesz tego:
źródło
Udało mi się to po wielu próbach dzięki wpisowi, którego już nie mogę znaleźć :-(
Exif wydaje się działać zawsze, trudność polegała na uzyskaniu ścieżki do pliku. Kod, który znalazłem, różni się między API starszymi niż 4.4 i późniejszymi niż 4.4. Zasadniczo identyfikator URI obrazu dla wersji 4.4+ zawiera „com.android.providers”. W przypadku tego typu identyfikatora URI kod używa DocumentsContract, aby uzyskać identyfikator obrazu, a następnie uruchamia zapytanie przy użyciu ContentResolver, podczas gdy w przypadku starszego zestawu SDK kod przechodzi bezpośrednio do zapytania o identyfikator URI za pomocą ContentResolver.
Oto kod (przepraszam, nie mogę wymienić tego, kto go opublikował):
źródło
Możesz po prostu odczytać ścieżkę z karty SD i wykonać następujący kod ... po obróceniu zastąpi istniejące zdjęcie ..
Nie: Exif nie działa na większości urządzeń, podaje błędne dane, więc dobrze jest zakodować obracanie przed zapisaniem w dowolnym stopniu, wystarczy zmienić wartość kąta w postRotate na dowolną.
źródło
Kod Kotlin:
źródło
Poprawiłem odpowiedź Teo Inke. Nie obraca już obrazu, chyba że jest to rzeczywiście konieczne. Jest też łatwiejszy do odczytania i powinien działać szybciej.
źródło
Pierwszą rzeczą, której potrzebujesz, jest prawdziwa ścieżka do pliku.Jeśli masz ją świetnie, jeśli używasz URI, użyj tej metody, aby uzyskać prawdziwą ścieżkę:
wyodrębnij swoją mapę bitową, na przykład:
możesz zamiast tego użyć decodeFile (), jeśli chcesz.
Teraz, gdy masz już mapę bitową i prawdziwą ścieżkę, uzyskaj orientację obrazu:
i na koniec obróć go do właściwej pozycji, na przykład:
To wszystko, masz teraz mapę bitową obróconą do właściwej pozycji.
Twoje zdrowie.
źródło
To działa, ale prawdopodobnie nie jest to najlepszy sposób, ale może komuś pomóc.
źródło
może to pomoże (obróć o 90 stopni) (u mnie to zadziałało)
źródło
Po otwarciu kursor powinien zostać zamknięty.
Oto przykład.
źródło
Stopniłem odpowiedź @Timmmm i @Manuel. Jeśli zastosujesz to rozwiązanie, nie otrzymasz wyjątku braku pamięci.
Ta metoda pobiera orientację obrazu:
Dlatego należy użyć tej metody do zmiany rozmiaru obrazu przed załadowaniem go do pamięci. W ten sposób nie otrzymasz wyjątku pamięci.
U mnie to działa idealnie. Mam nadzieję, że to pomoże komuś innemu
źródło
Ulepszenie powyższego rozwiązania przez Timmmm w celu dodania dodatkowego skalowania na końcu, aby upewnić się, że obraz mieści się w granicach:
źródło
Użyj poniższego kodu, aby poprawnie obrócić obraz:
źródło
Poniższe metody skalują ORAZ obracają mapę bitową zgodnie z orientacją:
Przykład:
źródło
Rozwiązałem problem, stosując następujące obejście. Zwróć uwagę, że skaluję również obraz, co było konieczne, aby uniknąć wyjątków OutOfMemoryExceptions.
Pamiętaj, że to rozwiązanie nie będzie działać poprawnie w przypadku obrazów portretowych lub odwróconych (dziękuję Timmmm za uwagę). Powyższe rozwiązanie Timmmm może być lepszym wyborem, jeśli jest to wymagane, a także wygląda bardziej elegancko: https://stackoverflow.com/a/8914291/449918
Twoje zdrowie
źródło