Изображение Android выбрано из галереи Ориентация всегда 0: Exif TAG
Когда я выбираю изображение из галереи, чтобы установить его на моем изображении в приложении Android, я вижу, что он перевернут на 180 или 270 или 90 градусов.
Чтобы проверить/решить эту проблему, я использовал ориентацию EXIF
но он всегда дает мне "0".
Я не могу решить, в чем проблема.
код:
Uri selectedImageUri = data.getData();
absolutePath = selectedImageUri.getPath();
exifMedia = new ExifInterface(absolutePath);
String exifOrint = exifMedia.getAttribute(ExifInterface.TAG_ORIENTATION);
exifOrientation = Integer.parseInt(exifOrint);
System.out.println("Orientation Tag is:"+exifOrientation);
/** Convert URI into byte */
ContentResolver cr = getBaseContext()
.getContentResolver();
InputStream inputStream = cr
.openInputStream(selectedImageUri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
rotatedBMP = getResizedBitmapImage(
bitmap, 100, 100,exifOrientation);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
rotatedBMP.compress(Bitmap.CompressFormat.PNG, 100,
stream);
byteArray = stream.toByteArray();
mimProfileImageBrowse.setImageBitmap(rotatedBMP);
метод:
public Bitmap getResizedBitmapImage(Bitmap bm, int newHeight, int newWidth, int exifOrientation) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
/**
* create a matrix for the manipulation
*/
Matrix matrix = new Matrix();
/**
* resize the bit map
*/
/*
1 = Horizontal (normal)
2 = Mirror horizontal
3 = Rotate 180
4 = Mirror vertical
5 = Mirror horizontal and rotate 270 CW
6 = Rotate 90 CW
7 = Mirror horizontal and rotate 90 CW
8 = Rotate 270 CW
*/
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
rotate = 45;
break;
default:
break;
}
matrix.postScale(scaleWidth, scaleHeight);
matrix.postRotate(rotate);
/**
* recreate the new Bitmap
*/
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
resizedBitmap = Bitmap.createScaledBitmap(bm, 65, 65, true);
return resizedBitmap;
}
Пожалуйста, помогите. Также matrix.postROTATE
не вращает растровые изображения. Я не знаю, почему.
Спасибо
Ответы
Ответ 1
После того, как вы получите Uri выбранного изображения, вызовите нижеуказанные функции, используя эти методы,
Как это,
Uri selectedImageUri = data.getData();
Bitmap bitmap = scaleImage(this,selectedImageUri);
Две функции для включения в вашу деятельность:
public static Bitmap scaleImage(Context context, Uri photoUri) throws IOException {
InputStream is = context.getContentResolver().openInputStream(photoUri);
BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, dbo);
is.close();
int rotatedWidth, rotatedHeight;
int orientation = getOrientation(context, photoUri);
if (orientation == 90 || orientation == 270) {
rotatedWidth = dbo.outHeight;
rotatedHeight = dbo.outWidth;
} else {
rotatedWidth = dbo.outWidth;
rotatedHeight = dbo.outHeight;
}
Bitmap srcBitmap;
is = context.getContentResolver().openInputStream(photoUri);
if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {
float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION);
float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION);
float maxRatio = Math.max(widthRatio, heightRatio);
// Create the bitmap from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (int) maxRatio;
srcBitmap = BitmapFactory.decodeStream(is, null, options);
} else {
srcBitmap = BitmapFactory.decodeStream(is);
}
is.close();
/*
* if the orientation is not 0 (or -1, which means we don't know), we
* have to do a rotation.
*/
if (orientation > 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
srcBitmap.getHeight(), matrix, true);
}
String type = context.getContentResolver().getType(photoUri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (type.equals("image/png")) {
srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
} else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
}
byte[] bMapArray = baos.toByteArray();
baos.close();
return BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);
}
public static int getOrientation(Context context, Uri photoUri) {
/* it on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
Чтобы получить Uri из файла, используйте это:
public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}
Q. Можете ли вы рассказать мне, что такое "MAX_IMAGE_DIMENSION"? - Дропал Мар 13 '13
A. его на основе вашего размера изображения или размера изображения, что вы хотите показать.. независимо от того, что это 60X60, затем 60, 100X100, затем 100 @Dhrupal
Ответ 2
Я думаю, вы не должны использовать "selectedImageUri.getPath()
", чтобы получить путь, поскольку он действительно не возвращает путь к файлу изображения. Вместо этого вы должны использовать ContentResolver
для запроса значения MediaStore.Images.ImageColumns.DATA
, который является фактическим путем изображения.
На самом деле, если вы хотите получить ориентацию, вам не нужно получать это из Exif, просто запрос значения MediaStore.Images.ImageColumns.ORIENTATION
может дать вам это.
Ответ 3
прошло много времени с допроса. но я встретился с той же проблемой и решил это. когда вы помещаете путь к файлу в contructor exifInterface, используйте реальный путь, например "/storage/sdcard0/DCIM/Camera/blahbalh.jpg", не используя что-то вроде /content:/media/external/images/media/blah, которое дает всегда 0 информации.
надеюсь, кому-то поможет. regrads.
К сожалению. ниже один - тот же подход. и здесь больше.
использовать это.
/**
* @ref http://stackoverflow.com/questions/3401579/get-filename-and-path-from-uri-from-mediastore
* @param contentUri
* @return
*/
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
Ответ 4
попробуйте под кодом: -
ExifInterface exif = new ExifInterface(filename);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
Bitmap bmRotated = rotateBitmap(bitmap, orientation);
вызов ниже метода: -
public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
try{
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;
}
}
catch (IOException e) {
e.printStackTrace();
return null;
}
return bitmap;
}
Ответ 5
Вы должны использовать функцию getRealPathFromURI:
public static String getRealPathFromURI(Context context, Uri uri,
String data) {
String[] largeFileProjection = { MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA };
String largeFileSort = MediaStore.Images.ImageColumns._ID + " DESC";
Cursor myCursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
largeFileProjection, null, null, largeFileSort);
String largeImagePath = "";
try {
myCursor.moveToFirst();
largeImagePath = myCursor
.getString(myCursor
.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
} finally {
myCursor.close();
}
return largeImagePath;
}
Ответ 6
Я не мог использовать метод курсора или интерфейса Exif для меня. Мне не удалось получить надежные номера вращения для передней и задней камер Samsung.
Для тех, кто ищет решение, которое работает как передними, так и задними камерами для Samsung и других крупных производителей, этот ответ nvhausid является потрясающим:
fooobar.com/questions/12188/...
Для тех, кто не хочет переходить по ссылке, подходящая магия - использовать CameraInfo, а не полагаться на EXIF.
Bitmap realImage = BitmapFactory.decodeByteArray(data, 0, data.length);
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(mCurrentCameraId, info);
Bitmap bitmap = rotate(realImage, info.orientation);
Полный код в ссылке.
Ответ 7
Когда изображение захвачено, оно хранит данные exif как информацию о типе вращения (портрет - пейзаж). Итак, единственное, что вам нужно проверить, это данные exif:
ExifInterface exifData = new ExifInterface(uri);
int orientation = exifData.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Matrix matrix;
switch (orientation) {
case 6:
matrix = new Matrix();
matrix.postRotate(90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
break;
case 3:
matrix = new Matrix();
matrix.postRotate(180);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
break;
case 8:
matrix = new Matrix();
matrix.postRotate(270);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
break;
default:
break;
Ответ 8
Вы уже проверили, были ли у вас установлены разрешения Write и Read в манифесте? потому что, если вы не установили их, вы не можете получить доступ к exif-данным вашего растрового изображения, я говорю об android M.
Это фрагмент для поворота растрового изображения на основе его exif dada.
public static Bitmap rotateBitmap(String filePath, Bitmap bitmap) {
ExifInterface exif;
try {
exif = new ExifInterface(filePath);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Log.d("EXIF", "Exif: " + orientation);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 3) {
matrix.postRotate(180);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 8) {
matrix.postRotate(270);
Log.d("EXIF", "Exif: " + orientation);
}
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}