我查看了一些链接,以获取从默认图库选择的图像的正确方向,在所有设备中都能正常工作。但是,exif标签总是返回0。如何获得一个确切的解决方案,使其在所有设备上都能正常工作?
我查看了一些链接,以获取从默认图库选择的图像的正确方向,在所有设备中都能正常工作。但是,exif标签总是返回0。如何获得一个确切的解决方案,使其在所有设备上都能正常工作?
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;
}
}
对我来说,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]));
}
对于那些阅读这篇文章的人,请确保使用Android Support Library中在2016年12月引入的exifinterface:
compile "com.android.support:exifinterface:25.1.0" // or newer
关于这个库的详细信息可以在对应的 Android Developers Blog 文章中找到:介绍 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;
}
https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en
我的建议是:不要浪费时间,使用它们。您可以通过一行代码解决问题:
Glide.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
int orientation = 0;
InputStream input = mContext.getContentResolver().openInputStream(uri);
if (input != null){
ExifInterface exif = new ExifInterface(input);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
input.close();
}
这是我完整的代码,用于从画廊中选择正确方向的位图,并且还可以设置最大尺寸。如果要使用它,请确保检查空返回情况。
public Bitmap getBitmapFromGalleryUri(Context mContext, Uri uri, Double maxSize)throws IOException {
int orientation = 0;
InputStream input = mContext.getContentResolver().openInputStream(uri);
if (input != null){
ExifInterface exif = new ExifInterface(input);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
//Log.d("Utils", "rotation value = " + orientation);
input.close();
}
input = mContext.getContentResolver().openInputStream(uri);
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
onlyBoundsOptions.inJustDecodeBounds = true;
onlyBoundsOptions.inDither = true;//optional
onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
try {
input.close();
} catch (NullPointerException e) {
e.printStackTrace();
}
if ((onlyBoundsOptions.outWidth == -1) || (onlyBoundsOptions.outHeight == -1)) {
return null;
}
int originalSize = (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) ? onlyBoundsOptions.outHeight : onlyBoundsOptions.outWidth;
double ratio = (originalSize > maxSize) ? (originalSize / maxSize) : 1.0;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = getPowerOfTwoForSampleRatio(ratio);
bitmapOptions.inDither = true; //optional
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//
input = mContext.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
try {
input.close();
} catch (NullPointerException e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
//Log.d("Utils", "rotation value = " + orientation);
int rotationInDegrees = exifToDegrees(orientation);
//Log.d("Utils", "rotationInDegrees value = " + rotationInDegrees);
if (orientation != 0) {
matrix.preRotate(rotationInDegrees);
}
int bmpWidth = 0;
try {
bmpWidth = bitmap.getWidth();
} catch (NullPointerException e) {
e.printStackTrace();
}
Bitmap adjustedBitmap = bitmap;
if (bmpWidth > 0) {
adjustedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
return adjustedBitmap;
}
private static int getPowerOfTwoForSampleRatio(double ratio){
int k = Integer.highestOneBit((int)Math.floor(ratio));
if(k==0) return 1;
else return k;
}
public 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;
}