2016-06-10 74 views
4

我想获取Exif数据,以便从Android图库或Google Photos等类似应用中挑选图像。下面是我使用从Uri获取图像文件的方法:使用Uri获取Exif数据

public static String getActualPathFromUri(@NonNull Context context, @NonNull Uri selectedImageUri) { 
     Bitmap bitmap = null; 
     try { 
      bitmap = getBitmapFromUri(context, selectedImageUri); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     if (bitmap == null) { 
      return null; 
     } 

     File imageFileFolder = new File(context.getCacheDir(), "example"); 
     if (!imageFileFolder.exists()) { 
      imageFileFolder.mkdir(); 
     } 

     FileOutputStream out = null; 

     File imageFileName = new File(imageFileFolder, "example-" + System.currentTimeMillis() + ".jpg"); 
     try { 
      out = new FileOutputStream(imageFileName); 
      bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); 
      out.flush(); 
      out.close(); 
     } catch (IOException e) { 

     } finally { 
      if (out != null) { 
       try { 
        out.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     return imageFileName.getAbsolutePath(); 
    } 

    private static Bitmap getBitmapFromUri(@NonNull Context context, @NonNull Uri uri) throws IOException { 

     ParcelFileDescriptor parcelFileDescriptor = 
       context.getContentResolver().openFileDescriptor(uri, "r"); 
     assert parcelFileDescriptor != null; 
     FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); 
     Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor); 
     parcelFileDescriptor.close(); 
} 

我从Uri选择加入而不是让系统文件名Bitmap的原因是因为该方法是零散的不同版本的Android。另外,在Google相册等应用中,有些照片直接从服务器上显示,并未存储在设备上,因此无法获取文件名。即使我得到的文件名,我试图在我的应用程序中使用时得到Security Exception

这种方法的问题是,当我得到Bitmap,我没有得到Exif数据。但我需要Exif数据并将其附加到我保存在我的cache文件夹中的文件中,以便当我将图像上载到服务器时,它将获取图像以及Exif,以便它可以进行一些进一步处理。原因是,我需要将其保存为文件或至少获取文件(如果它已存在于系统中),因为Retrofit需要一个File对象,然后该对象将被转换为TypedFile并使用Multipart请求发送到服务器。因此,我怎样才能从任何类型的图像Uri(本地或服务器)上准确获取Exif信息,然后将图像与其Exif数据一起保存,以便我可以将其发送到服务器。

回答

1

下面的代码可以帮助你

String path = FileUtility.getRealPathFromURI(context, Uri.parse(bitmapUri.getPath()); 
ExifInterface exif = new ExifInterface(path); 
rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL); 

FileUtility.java

public static String getRealPathFromURI(Context context, Uri contentUri) { 
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
    return getPathForV19AndUp(context, contentUri); 
} else { 
    return getPathForPreV19(context, contentUri); 
} 
} 


public static String getPathForPreV19(Context context, Uri contentUri) { 
String res = null; 

String[] proj = { MediaStore.Images.Media.DATA }; 
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null); 
if(cursor.moveToFirst()){; 
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
    res = cursor.getString(column_index); 
} 
cursor.close(); 

return res; 
} 

@TargetApi(Build.VERSION_CODES.KITKAT) 
public static String getPathForV19AndUp(Context context, Uri contentUri) { 
String wholeID = DocumentsContract.getDocumentId(contentUri); 

// Split at colon, use second item in the array 
String id = wholeID.split(":")[1]; 
String[] column = { MediaStore.Images.Media.DATA }; 

// where id is equal to 
String sel = MediaStore.Images.Media._ID + "=?"; 
Cursor cursor = context.getContentResolver(). 
     query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
       column, sel, new String[]{ id }, null); 

String filePath = ""; 
int columnIndex = cursor.getColumnIndex(column[0]); 
if (cursor.moveToFirst()) { 
    filePath = cursor.getString(columnIndex); 
} 

cursor.close(); 
return filePath; 
} 
+1

什么是'FileUtility'? –

+0

工作得很好。谢谢!! – javatar