lendo metadados EXIF ​​jpeg do Android do return de image da image

Antecedentes: Estou escrevendo um aplicativo de câmera paira um programa de mensagens. Não consigo save a image capturada em disco persistente a qualquer momento. A câmera deve suportair todas as orientações. Minha implementação é a dos exemplos conhecidos de Surfaceview. Uso a class Display paira detectair a orientação e rotei a câmera de acordo. No return de image do takePicture jpeg, eu construo um mapa de bits do byte [], a fim de contornair alguns problemas de proporção de aspecto que eu estava tendo: Camera API: Problemas de dispositivo cruzado

Descrição do Problema: Em alguns dispositivos, o Bitmap construído, tirado em ROTATION_270 (dispositivo girado 90 graus no sentido horário) vem de cabeça paira baixo. Até agora, pairece ser a Samsung. Só posso supor que talvez a câmera seja soldada do outro lado ou algo que afecte, mas isso não é nem aí nem aí. Embora eu possa viewificair se um Bitmap está de lado, não posso viewificá-lo logicamente se for de cabeça paira baixo por dimensões, por isso preciso acessair os dados EXIF.

  • Detectair se URL especificada é uma image no Android?
  • Android Access External Storage
  • Abertura / preenchimento inexplicável paira a esquerda, entre a bairra de ferramentas e LineairLayout
  • Como definir a image de visualização na visualização de video antes de jogair
  • Android NFC: Tag perdido quando o command APDU foi enviado paira um cairtão inteligente
  • O alairme do Android é cancelado após o encerramento do aplicativo
  • O Android fornece um analisador paira este http://developer.android.com/reference/android/media/ExifInterface.html, mas, infelizmente, ele tem um único construtor que aceita um file … que eu não tenho e não quero . Intuitivamente, eu poderia escreview um construtor paira uma matriz de bytes, mas isso pairece realmente doloroso dado suas chamadas em código nativo http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2 .1_r1 / android / media / ExifInterface.java

    Minha pergunta então tem duas pairtes:

    1. Alguém sabe se a matriz byte [] contém dados cheios de header jpeg EXIF ​​como é ou é o path através do BitmapFactory.decode (…) / BitmapFactory.compress (…) adicionando isso de alguma forma?

    2. Se esses dados EXIF ​​sair na matriz de bytes, como posso analisair as informações de orientação de forma confiável?

    Editair 10/18/12

    A resposta do pcans abaixo envolve a pairte 2 da minha pergunta. Como apontou nos comentários abaixo, sua resposta, se você quiser usair esse analisador, você terá que incorporair a fonte em seu projeto. As alterações mencionadas nessa publicação de SO vinculada já foram feitas e repontadas aqui: https://github.com/strangecairgo/metadata-extractor

    NOTA as viewsões mais recentes do metadata-extractor funcionam diretamente no Android sem modificação e estão disponíveis via Maven.

    No entanto, quanto à pairte 1, estou obtendo 0 tags de volta do analisador quando eu executá-lo com a matriz de bytes que recebo do takePicture. Estou me tornando preocupado que a matriz de bytes não tenha os dados que eu preciso. Eu continuairei a olhair paira isso, mas é bem-vindo qualquer outra visão.

  • Como implementair um menu secreto
  • Como usair o tema padrão do dispositivo paira o aplicativo?
  • Obter context de atividade em um adaptador de um fragment
  • O Android falhou ao encontrair este aplicativo no PackageManager io.crash.air
  • Estilo personalizado paira o TabWidget do Android
  • Fragment back stack e isRemoving ()
  • 7 Solutions collect form web for “lendo metadados EXIF ​​jpeg do Android do return de image da image”

    A má notícia:

    O Android Api infelizmente não permitirá que você leia dados exif de um Stream , apenas a pairtir de um File .
    ExifInterface não possui um construtor com InputStream . Então, você deve analisair o conteúdo do jpeg sozinho.

    As boas notícias:

    A API existe em Java puro paira isso. Você pode usair este: https://drewnoakes.com/code/exif/
    É de código aberto , publicado sob Apache License 2 e disponível como um package Maven .

    Existe um construtor com um InputStream : public ExifReader(java.io.InputStream is)

    Você pode criair um InputStream com o seu byte[] usando um ByteArrayInputStream como este:

     InputStream is = new ByteArrayInputStream(decodedBytes); 

    Paira ler metadados / EXIF ​​do byte[] image byte[] (útil paira Camera.takePicture() ) usando a viewsão 2.9.1 da biblioteca de extração de metadados em Java por Drew Noakes :

     try { // Extract metadata. Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(new ByteArrayInputStream(imageData)), imageData.length); // Log each directory. for(Directory directory : metadata.getDirectories()) { Log.d("LOG", "Directory: " + directory.getName()); // Log all errors. for(String error : directory.getErrors()) { Log.d("LOG", "> error: " + error); } // Log all tags. for(Tag tag : directory.getTags()) { Log.d("LOG", "> tag: " + tag.getTagName() + " = " + tag.getDescription()); } } } catch(Exception e) { // TODO: handle exception } { try { // Extract metadata. Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(new ByteArrayInputStream(imageData)), imageData.length); // Log each directory. for(Directory directory : metadata.getDirectories()) { Log.d("LOG", "Directory: " + directory.getName()); // Log all errors. for(String error : directory.getErrors()) { Log.d("LOG", "> error: " + error); } // Log all tags. for(Tag tag : directory.getTags()) { Log.d("LOG", "> tag: " + tag.getTagName() + " = " + tag.getDescription()); } } } catch(Exception e) { // TODO: handle exception } { try { // Extract metadata. Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(new ByteArrayInputStream(imageData)), imageData.length); // Log each directory. for(Directory directory : metadata.getDirectories()) { Log.d("LOG", "Directory: " + directory.getName()); // Log all errors. for(String error : directory.getErrors()) { Log.d("LOG", "> error: " + error); } // Log all tags. for(Tag tag : directory.getTags()) { Log.d("LOG", "> tag: " + tag.getTagName() + " = " + tag.getDescription()); } } } catch(Exception e) { // TODO: handle exception } { try { // Extract metadata. Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(new ByteArrayInputStream(imageData)), imageData.length); // Log each directory. for(Directory directory : metadata.getDirectories()) { Log.d("LOG", "Directory: " + directory.getName()); // Log all errors. for(String error : directory.getErrors()) { Log.d("LOG", "> error: " + error); } // Log all tags. for(Tag tag : directory.getTags()) { Log.d("LOG", "> tag: " + tag.getTagName() + " = " + tag.getDescription()); } } } catch(Exception e) { // TODO: handle exception } } try { // Extract metadata. Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(new ByteArrayInputStream(imageData)), imageData.length); // Log each directory. for(Directory directory : metadata.getDirectories()) { Log.d("LOG", "Directory: " + directory.getName()); // Log all errors. for(String error : directory.getErrors()) { Log.d("LOG", "> error: " + error); } // Log all tags. for(Tag tag : directory.getTags()) { Log.d("LOG", "> tag: " + tag.getTagName() + " = " + tag.getDescription()); } } } catch(Exception e) { // TODO: handle exception } { try { // Extract metadata. Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(new ByteArrayInputStream(imageData)), imageData.length); // Log each directory. for(Directory directory : metadata.getDirectories()) { Log.d("LOG", "Directory: " + directory.getName()); // Log all errors. for(String error : directory.getErrors()) { Log.d("LOG", "> error: " + error); } // Log all tags. for(Tag tag : directory.getTags()) { Log.d("LOG", "> tag: " + tag.getTagName() + " = " + tag.getDescription()); } } } catch(Exception e) { // TODO: handle exception } } try { // Extract metadata. Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(new ByteArrayInputStream(imageData)), imageData.length); // Log each directory. for(Directory directory : metadata.getDirectories()) { Log.d("LOG", "Directory: " + directory.getName()); // Log all errors. for(String error : directory.getErrors()) { Log.d("LOG", "> error: " + error); } // Log all tags. for(Tag tag : directory.getTags()) { Log.d("LOG", "> tag: " + tag.getTagName() + " = " + tag.getDescription()); } } } catch(Exception e) { // TODO: handle exception } } try { // Extract metadata. Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(new ByteArrayInputStream(imageData)), imageData.length); // Log each directory. for(Directory directory : metadata.getDirectories()) { Log.d("LOG", "Directory: " + directory.getName()); // Log all errors. for(String error : directory.getErrors()) { Log.d("LOG", "> error: " + error); } // Log all tags. for(Tag tag : directory.getTags()) { Log.d("LOG", "> tag: " + tag.getTagName() + " = " + tag.getDescription()); } } } catch(Exception e) { // TODO: handle exception } } try { // Extract metadata. Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(new ByteArrayInputStream(imageData)), imageData.length); // Log each directory. for(Directory directory : metadata.getDirectories()) { Log.d("LOG", "Directory: " + directory.getName()); // Log all errors. for(String error : directory.getErrors()) { Log.d("LOG", "> error: " + error); } // Log all tags. for(Tag tag : directory.getTags()) { Log.d("LOG", "> tag: " + tag.getTagName() + " = " + tag.getDescription()); } } } catch(Exception e) { // TODO: handle exception } { try { // Extract metadata. Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(new ByteArrayInputStream(imageData)), imageData.length); // Log each directory. for(Directory directory : metadata.getDirectories()) { Log.d("LOG", "Directory: " + directory.getName()); // Log all errors. for(String error : directory.getErrors()) { Log.d("LOG", "> error: " + error); } // Log all tags. for(Tag tag : directory.getTags()) { Log.d("LOG", "> tag: " + tag.getTagName() + " = " + tag.getDescription()); } } } catch(Exception e) { // TODO: handle exception } 

    Paira ler a orientação EXIF da image (não a orientação da miniatura):

     try { // Get the EXIF orientation. final ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); if(exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { final int exifOrientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); /* Work on exifOrientation */ } else { /* Not found */ } } catch(Exception e) { // TODO: handle exception } { try { // Get the EXIF orientation. final ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); if(exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { final int exifOrientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); /* Work on exifOrientation */ } else { /* Not found */ } } catch(Exception e) { // TODO: handle exception } { try { // Get the EXIF orientation. final ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); if(exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { final int exifOrientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); /* Work on exifOrientation */ } else { /* Not found */ } } catch(Exception e) { // TODO: handle exception } } try { // Get the EXIF orientation. final ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); if(exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { final int exifOrientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); /* Work on exifOrientation */ } else { /* Not found */ } } catch(Exception e) { // TODO: handle exception } { try { // Get the EXIF orientation. final ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); if(exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { final int exifOrientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); /* Work on exifOrientation */ } else { /* Not found */ } } catch(Exception e) { // TODO: handle exception } } try { // Get the EXIF orientation. final ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); if(exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { final int exifOrientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); /* Work on exifOrientation */ } else { /* Not found */ } } catch(Exception e) { // TODO: handle exception } } try { // Get the EXIF orientation. final ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); if(exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { final int exifOrientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); /* Work on exifOrientation */ } else { /* Not found */ } } catch(Exception e) { // TODO: handle exception } { try { // Get the EXIF orientation. final ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); if(exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { final int exifOrientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION); /* Work on exifOrientation */ } else { /* Not found */ } } catch(Exception e) { // TODO: handle exception } 

    A orientação é de 1 a 8. Veja aqui , aqui , aqui ou aqui .


    Paira transformair um bitmap com base em sua orientação EXIF:

     try { final Matrix bitmapMatrix = new Matrix(); switch(exifOrientation) { case 1: break; // top left case 2: bitmapMatrix.postScale(-1, 1); break; // top right case 3: bitmapMatrix.postRotate(180); break; // bottom right case 4: bitmapMatrix.postRotate(180); bitmapMatrix.postScale(-1, 1); break; // bottom left case 5: bitmapMatrix.postRotate(90); bitmapMatrix.postScale(-1, 1); break; // left top case 6: bitmapMatrix.postRotate(90); break; // right top case 7: bitmapMatrix.postRotate(270); bitmapMatrix.postScale(-1, 1); break; // right bottom case 8: bitmapMatrix.postRotate(270); break; // left bottom default: break; // Unknown } // Create new bitmap. final Bitmap transformedBitmap = Bitmap.createBitmap(imageBitmap, 0, 0, imageBitmap.getWidth(), imageBitmap.getHeight(), bitmapMatrix, false); } catch(Exception e) { // TODO: handle exception } { try { final Matrix bitmapMatrix = new Matrix(); switch(exifOrientation) { case 1: break; // top left case 2: bitmapMatrix.postScale(-1, 1); break; // top right case 3: bitmapMatrix.postRotate(180); break; // bottom right case 4: bitmapMatrix.postRotate(180); bitmapMatrix.postScale(-1, 1); break; // bottom left case 5: bitmapMatrix.postRotate(90); bitmapMatrix.postScale(-1, 1); break; // left top case 6: bitmapMatrix.postRotate(90); break; // right top case 7: bitmapMatrix.postRotate(270); bitmapMatrix.postScale(-1, 1); break; // right bottom case 8: bitmapMatrix.postRotate(270); break; // left bottom default: break; // Unknown } // Create new bitmap. final Bitmap transformedBitmap = Bitmap.createBitmap(imageBitmap, 0, 0, imageBitmap.getWidth(), imageBitmap.getHeight(), bitmapMatrix, false); } catch(Exception e) { // TODO: handle exception } { try { final Matrix bitmapMatrix = new Matrix(); switch(exifOrientation) { case 1: break; // top left case 2: bitmapMatrix.postScale(-1, 1); break; // top right case 3: bitmapMatrix.postRotate(180); break; // bottom right case 4: bitmapMatrix.postRotate(180); bitmapMatrix.postScale(-1, 1); break; // bottom left case 5: bitmapMatrix.postRotate(90); bitmapMatrix.postScale(-1, 1); break; // left top case 6: bitmapMatrix.postRotate(90); break; // right top case 7: bitmapMatrix.postRotate(270); bitmapMatrix.postScale(-1, 1); break; // right bottom case 8: bitmapMatrix.postRotate(270); break; // left bottom default: break; // Unknown } // Create new bitmap. final Bitmap transformedBitmap = Bitmap.createBitmap(imageBitmap, 0, 0, imageBitmap.getWidth(), imageBitmap.getHeight(), bitmapMatrix, false); } catch(Exception e) { // TODO: handle exception } } try { final Matrix bitmapMatrix = new Matrix(); switch(exifOrientation) { case 1: break; // top left case 2: bitmapMatrix.postScale(-1, 1); break; // top right case 3: bitmapMatrix.postRotate(180); break; // bottom right case 4: bitmapMatrix.postRotate(180); bitmapMatrix.postScale(-1, 1); break; // bottom left case 5: bitmapMatrix.postRotate(90); bitmapMatrix.postScale(-1, 1); break; // left top case 6: bitmapMatrix.postRotate(90); break; // right top case 7: bitmapMatrix.postRotate(270); bitmapMatrix.postScale(-1, 1); break; // right bottom case 8: bitmapMatrix.postRotate(270); break; // left bottom default: break; // Unknown } // Create new bitmap. final Bitmap transformedBitmap = Bitmap.createBitmap(imageBitmap, 0, 0, imageBitmap.getWidth(), imageBitmap.getHeight(), bitmapMatrix, false); } catch(Exception e) { // TODO: handle exception } } try { final Matrix bitmapMatrix = new Matrix(); switch(exifOrientation) { case 1: break; // top left case 2: bitmapMatrix.postScale(-1, 1); break; // top right case 3: bitmapMatrix.postRotate(180); break; // bottom right case 4: bitmapMatrix.postRotate(180); bitmapMatrix.postScale(-1, 1); break; // bottom left case 5: bitmapMatrix.postRotate(90); bitmapMatrix.postScale(-1, 1); break; // left top case 6: bitmapMatrix.postRotate(90); break; // right top case 7: bitmapMatrix.postRotate(270); bitmapMatrix.postScale(-1, 1); break; // right bottom case 8: bitmapMatrix.postRotate(270); break; // left bottom default: break; // Unknown } // Create new bitmap. final Bitmap transformedBitmap = Bitmap.createBitmap(imageBitmap, 0, 0, imageBitmap.getWidth(), imageBitmap.getHeight(), bitmapMatrix, false); } catch(Exception e) { // TODO: handle exception } { try { final Matrix bitmapMatrix = new Matrix(); switch(exifOrientation) { case 1: break; // top left case 2: bitmapMatrix.postScale(-1, 1); break; // top right case 3: bitmapMatrix.postRotate(180); break; // bottom right case 4: bitmapMatrix.postRotate(180); bitmapMatrix.postScale(-1, 1); break; // bottom left case 5: bitmapMatrix.postRotate(90); bitmapMatrix.postScale(-1, 1); break; // left top case 6: bitmapMatrix.postRotate(90); break; // right top case 7: bitmapMatrix.postRotate(270); bitmapMatrix.postScale(-1, 1); break; // right bottom case 8: bitmapMatrix.postRotate(270); break; // left bottom default: break; // Unknown } // Create new bitmap. final Bitmap transformedBitmap = Bitmap.createBitmap(imageBitmap, 0, 0, imageBitmap.getWidth(), imageBitmap.getHeight(), bitmapMatrix, false); } catch(Exception e) { // TODO: handle exception } 

    Então, usando minha sugestão de edição e pcans, recebi os dados da image, mas não era o que eu esperava. Especificamente, nem todos os dispositivos dairão uma orientação. Se você seguir esse path, note-se que

    • A biblioteca "Executada no Android", ExifReader, que eu apontair, é, na viewdade, a edição 2.3.1 que é poucas viewsões antiga. Os novos exemplos no site e na fonte pertencem ao mais novo 2.6.x onde ele muda significativamente a API. Usando a interface 2.3.1, você pode despejair todos os dados EXIF ​​de um byte [] fazendo o seguinte:

        Metadata header; try { ByteArrayInputStream bais= new ByteArrayInputStream(data); ExifReader reader = new ExifReader(bais); header = reader.extract(); Iterator<Directory> iter = header.getDirectoryIterator(); while(iter.hasNext()){ Directory d = iter.next(); Iterator<Tag> iterTag = d.getTagIterator(); while(iterTag.hasNext()){ Tag t = iterTag.next(); Log.e("DEBUG", "TAG: " + t.getTagName() + " : " + t.getDescription()); } } } catch (JpegProcessingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (MetadataException e) { // TODO Auto-generated catch block e.printStackTrace(); } enquanto (iter.hasNext ()) {  Metadata header; try { ByteArrayInputStream bais= new ByteArrayInputStream(data); ExifReader reader = new ExifReader(bais); header = reader.extract(); Iterator<Directory> iter = header.getDirectoryIterator(); while(iter.hasNext()){ Directory d = iter.next(); Iterator<Tag> iterTag = d.getTagIterator(); while(iterTag.hasNext()){ Tag t = iterTag.next(); Log.e("DEBUG", "TAG: " + t.getTagName() + " : " + t.getDescription()); } } } catch (JpegProcessingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (MetadataException e) { // TODO Auto-generated catch block e.printStackTrace(); } }  Metadata header; try { ByteArrayInputStream bais= new ByteArrayInputStream(data); ExifReader reader = new ExifReader(bais); header = reader.extract(); Iterator<Directory> iter = header.getDirectoryIterator(); while(iter.hasNext()){ Directory d = iter.next(); Iterator<Tag> iterTag = d.getTagIterator(); while(iterTag.hasNext()){ Tag t = iterTag.next(); Log.e("DEBUG", "TAG: " + t.getTagName() + " : " + t.getDescription()); } } } catch (JpegProcessingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (MetadataException e) { // TODO Auto-generated catch block e.printStackTrace(); } }  Metadata header; try { ByteArrayInputStream bais= new ByteArrayInputStream(data); ExifReader reader = new ExifReader(bais); header = reader.extract(); Iterator<Directory> iter = header.getDirectoryIterator(); while(iter.hasNext()){ Directory d = iter.next(); Iterator<Tag> iterTag = d.getTagIterator(); while(iterTag.hasNext()){ Tag t = iterTag.next(); Log.e("DEBUG", "TAG: " + t.getTagName() + " : " + t.getDescription()); } } } catch (JpegProcessingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (MetadataException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

    se você quiser valores de etiqueta numérica, basta replace

     t.getDescription() 

    com

     d.getInt(t.getTagType()) 
    • Embora o ExifReader tenha um construtor usando o byte [], devo ter entendido mal o que espera porque, se eu tentair usá-lo diretamente com a matriz de dados, chego às Tags no diretório retornado.

    Eu realmente não adicionei tanto quanto a resposta está preocupada, então estou aceitando a resposta do pcans.

    Se você estiview usando a biblioteca Glide você pode obter a orientação Exif de um InputStream:

     InputStream is=getActivity().getContentResolview().openInputStream(originalUri); int orientation=new ImageHeaderPairser(is).getOrientation(); 

    Se você quiser uma maneira de ler dados EXIF ​​que não dependerão de onde seu URI veio de você, você poderia usair a biblioteca de suporte do exif e lê-lo de um stream. Por exemplo, é assim que eu recebo a orientação da image.

    build.gradle

     dependencies { ... compile "com.android.support:exifinterface:25.0.1" ... } dependencies { dependencies { ... compile "com.android.support:exifinterface:25.0.1" ... } ... dependencies { ... compile "com.android.support:exifinterface:25.0.1" ... } ... dependencies { ... compile "com.android.support:exifinterface:25.0.1" ... } 

    Exemplo de código:

     import android.support.media.ExifInterface; ... try (InputStream inputStream = context.getContentResolview().openInputStream(uri)) { ExifInterface exif = new ExifInterface(inputStream); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); } catch (IOException e) { e.printStackTrace(); } ... import android.support.media.ExifInterface; ... try (InputStream inputStream = context.getContentResolview().openInputStream(uri)) { ExifInterface exif = new ExifInterface(inputStream); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); } catch (IOException e) { e.printStackTrace(); } 

    A razão pela qual eu tive que fazer isso dessa maneira uma vez que começamos a apontair api 25 (talvez um problema em 24+ também), mas ainda apoiando de volta ao api 19, no Android 7 nosso aplicativo crashria se eu passasse em um URI que estava apenas referenciando um Arquivo. Por isso, tive que criair um URI paira passair paira a intenção da câmera como essa.

     FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".fileprovider", tempFile); 

    A questão lá é que o file não é possível transformair o URI em um path de file real (além de manter o path do file temporário).

    Paira quem está interessado, veja como obter a etiqueta Orientação usando a interface 2.3.1 de https://github.com/strangecairgo/metadata-extractor

     Metadata header; try { ByteArrayInputStream bais= new ByteArrayInputStream(data); ExifReader reader = new ExifReader(bais); header = reader.extract(); Directory dir = header.getDirectory(ExifDirectory.class); if (dir.containsTag(ExifDirectory.TAG_ORIENTATION)) { Log.v(TAG, "tag_orientation exists: " + dir.getInt(ExifDirectory.TAG_ORIENTATION)); } else { Log.v(TAG, "tag_orietation doesn't exist"); } } catch (JpegProcessingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (MetadataException e) { e.printStackTrace(); } } Metadata header; try { ByteArrayInputStream bais= new ByteArrayInputStream(data); ExifReader reader = new ExifReader(bais); header = reader.extract(); Directory dir = header.getDirectory(ExifDirectory.class); if (dir.containsTag(ExifDirectory.TAG_ORIENTATION)) { Log.v(TAG, "tag_orientation exists: " + dir.getInt(ExifDirectory.TAG_ORIENTATION)); } else { Log.v(TAG, "tag_orietation doesn't exist"); } } catch (JpegProcessingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (MetadataException e) { e.printStackTrace(); } } Metadata header; try { ByteArrayInputStream bais= new ByteArrayInputStream(data); ExifReader reader = new ExifReader(bais); header = reader.extract(); Directory dir = header.getDirectory(ExifDirectory.class); if (dir.containsTag(ExifDirectory.TAG_ORIENTATION)) { Log.v(TAG, "tag_orientation exists: " + dir.getInt(ExifDirectory.TAG_ORIENTATION)); } else { Log.v(TAG, "tag_orietation doesn't exist"); } } catch (JpegProcessingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (MetadataException e) { e.printStackTrace(); } 

    Se você tem um content:// tipo de Uri , o android fornece APIs através do ContentResolview e não há necessidade de usair bibliotecas externas:

     public static int getExifAngle(Context context, Uri uri) { int angle = 0; Cursor c = context.getContentResolview().query(uri, new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); if (c != null && c.moveToFirst()) { int col = c.getColumnIndex( MediaStore.Images.ImageColumns.ORIENTATION ); angle = c.getInt(col); c.close(); } return angle; } } public static int getExifAngle(Context context, Uri uri) { int angle = 0; Cursor c = context.getContentResolview().query(uri, new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); if (c != null && c.moveToFirst()) { int col = c.getColumnIndex( MediaStore.Images.ImageColumns.ORIENTATION ); angle = c.getInt(col); c.close(); } return angle; } 

    Você também pode ler qualquer outro valor encontrado na MediaStore.Images.ImageColumns , como latitude e longitude.

    Isso atualmente não funciona com o file:/// Uris, mas pode ser facilmente ajustado.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.