Как получить правильную ориентацию изображения, выбранного из галереи изображений по умолчанию
Я просмотрел некоторые ссылки, чтобы получить правильную ориентацию изображения, выбранную из галереи изображений по умолчанию, которая будет работать стандартно во всех устройствах, тег exif всегда возвращает 0.
Значение тега ориентации EXIF всегда 0 для изображения, сделанного с помощью приложения для портфолио с вертикальной камерой
Тег ориентации Exif возвращает 0
Данные Exif TAG_ORIENTATION всегда 0
http://mobisocial.stanford.edu/news/2011/08/rotating-images-in-android/
Как получить точное решение, которое будет работать на всех устройствах?
Ответы
Ответ 1
Если изображение (фотография) было выполнено программой, сделанной вами, вы должны установить Parameters.setRotation с правильным значением вращения.
Это, в зависимости от привода камеры, поворачивает изображение перед сохранением или сохраняет значение вращения в exif TAG_ORIENTATION.
Поэтому, если TAG_ORIENTATION имеет значение null или ноль, изображение находится в правильной ориентации, иначе вы должны повернуть изображение в соответствии со значением в TAG_ORIENTATION.
КОД
Получить ориентацию из EXIF:
ExifInterface exif = null;
try {
exif = new ExifInterface(path);
} catch (IOException e) {
e.printStackTrace();
}
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
Поверните растровое изображение:
Bitmap bmRotated = rotateBitmap(bitmap, orientation);
Способ поворота растрового изображения:
public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try {
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
}
catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
}
}
Ответ 2
Для меня ExifInterface работал довольно хорошо:
ExifInterface exifInterface = new ExifInterface(imagePath);
degree = Integer.parseInt(exifInterface.getAttribute(ExifInterface.TAG_ORIENTATION));
или вы можете попытаться получить информацию об изображении с помощью MediaStore
следующим образом:
String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
Cursor cur = managedQuery(imageUri, orientationColumn, null, null, null);
int orientation = -1;
if (cur != null && cur.moveToFirst()) {
orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
}
Аналогичное решение: ExifInterface всегда возвращает 1
Надеюсь, это поможет..:)
Ответ 3
Я последовал за последним ответом, и я попытался создать систему для управления изображениями, поворота, изменения размера, кеширования и загрузки в ImageViews, и я могу сказать, что это ад. Даже когда все это было сделано, сбои иногда вызывают OutOfMemory в некоторых устройствах. Ответ правильный, но управлять Bitmaps в Android сложно.
Моя задача - не изобретать колесо, он имеет идеальный дизайн. 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);
Ответ 4
Для тех, кто приходит на этот пост, обязательно используйте exifinterface из Библиотеки поддержки Android, которая была представлена в декабре 2016 года:
compile "com.android.support:exifinterface:25.1.0" // or newer
Подробную информацию об этой библиотеке можно найти в соответствующей статье в блоге разработчиков Android: Знакомство с библиотекой поддержки ExifInterface
Они также включали пример кода для обработки информации о ротации, хранящейся в интерфейсе exif:
int rotation = 0;
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotation = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotation = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotation = 270;
break;
}