Como corrigir a orientação das fotos no Android

Como corrigir a orientação das fotos no Android
jefferson.silva
jefferson.silva

Compartilhe

Imagina que você tá usando o seu aplicativo bacana pra tirar fotos e aplicar uns filtros marotos. Você vira o celular de lado para enquadrar melhor a foto e quando vai ver o resultado percebe que a foto saiu desse jeito:

Por que a orientação está incorreta?

Mas por que será que isso aconteceu?

Isso acontece porque o sensor da câmera é fixo e não sabe como o dispositivo está posicionado quando a foto é tirada. O papel dele é simplesmente capturar a imagem. Ah, mas quando tiramos uma foto com o celular virado de lado e abrimos a foto na galeria ela tá com a orientação correta!

Banner da Escola de Mobile: Matricula-se na escola de Mobile. Junte-se a uma comunidade de mais de 500 mil estudantes. Na Alura você tem acesso a todos os cursos em uma única assinatura; tem novos lançamentos a cada semana; desafios práticos. Clique e saiba mais!

Verdade! Isso mostra pra gente que tem alguém no meio do caminho fazendo algum tipo de correção pra mostrar a foto direitinho. Bom, o sensor da câmera é fixo mas sabemos que as câmeras digitais e também nossos smartphones tem aqueles sensores de orientação pra saber quando devem virar a tela. O que eles fazem então é salvar a imagem juntamente com essa informação da orientação justamente pra que a gente consiga corrigir depois.

Pra salvar essas informações extras, praticamente toda câmera digital salva as imagens no formato Exif que permite armazenar algumas tags com informações como data, hora, geolocalização e também a orientação da câmera no momento da captura. Isso significa que para mostrar uma foto no seu aplicativo com a orientação correta, você só precisa conseguir ler esses dados extras e descobrir qual correção aplicar antes de exibir a foto!

Mãos à obra então! Vamos criar uma classe que consiga devolver pra gente um Bitmap corrigido a partir do caminho de uma foto. Usaremos a classe ExifInterface para acessar as informações extras da imagem e descobrir a orientação da foto:


public class CarregadorDeFoto { 
    public static Bitmap carrega(String caminhoFoto) {
        ExifInterface exif = new ExifInterface(caminhoFoto); 
        String orientacao = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
        }
}

Agora que temos a orientação, só precisamos descobrir qual rotação devemos aplicar ao abrir o Bitmap. Para isso, vamos comparar a orientação que obtivemos da ExifInterface com algumas constantes que já estão prontas. Como essas constantes são do tipo inteiro, vamos ter que converter a orientação que pegamos da ExifInterface pra inteiro antes de fazer a comparação:


public class CarregadorDeFoto {

    public static Bitmap carrega(String caminhoFoto) {
        ExifInterface exif = new ExifInterface(caminhoFoto); 
        String orientacao = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
        int codigoOrientacao = Integer.parseInt(orientacao);

switch (codigoOrientacao) { 
    // rotaciona 0 graus no sentido horário case 
    case ExifInterface.ORIENTATION_NORMAL: 
    // rotaciona 90 graus no sentido horário case 
    ExifInterface.ORIENTATION_ROTATE_90: 
    // rotaciona 180 graus no sentido horário case
    ExifInterface.ORIENTATION_ROTATE_180:   
    // rotaciona 270 graus no sentido horário
    ExifInterface.ORIENTATION_ROTATE_270:
} } }

Agora só precisamos criar mais um método que abra a imagem como um Bitmap e faça a rotação de acordo com a correção a ser aplicada.


private Bitmap abreFotoERotaciona(String caminhoFoto, int angulo) { 
    // Abre o bitmap a partir do caminho da foto Bitmap 
    bitmap = BitmapFactory.decodeFile(caminhoFoto);

// Prepara a operação de rotação com o ângulo escolhido 
    Matrix matrix = new Matrix(); matrix.postRotate(angulo);

// Cria um novo bitmap a partir do original já com a rotação aplicada
 return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
 }

Pronto! Agora só precisamos utilizar esse método na nossa classe que carrega as fotos. Veja como fica o código completo:


public class CarregadorDeFoto { 
    public static Bitmap carrega(String caminhoFoto) {
        ExifInterface exif = new ExifInterface(caminhoFoto); 
        String orientacao = exif.getAttribute(ExifInterface.TAG_ORIENTATION); 
        int codigoOrientacao = Integer.parseInt(orientacao);

switch (codigoOrientacao) { 
case ExifInterface.ORIENTATION_NORMAL: return abreFotoERotaciona(caminhoFoto, 0);
case ExifInterface.ORIENTATION_ROTATE_90: return abreFotoERotaciona(caminhoFoto, 90);case ExifInterface.ORIENTATION_ROTATE_180: return abreFotoERotaciona(caminhoFoto,180);
case ExifInterface.ORIENTATION_ROTATE_270: return abreFotoERotaciona(caminhoFoto,270);
} }

private Bitmap abreFotoERotaciona(String caminhoFoto, int angulo) { 
    // Abre o bitmap a partir do caminho da foto Bitmap 
    bitmap = BitmapFactory.decodeFile(caminhoFoto);

// Prepara a operação de rotação com o ângulo escolhido 
    Matrix matrix = new Matrix(); matrix.postRotate(angulo);

// Cria um novo bitmap a partir do original já com a rotação aplicada
 return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } }

Legal! Então agora só precisamos usar essa classe toda vez que formos carregar uma imagem. Então se a gente tiver uma Activity com uma ImageView pra mostrar uma foto, poderíamos usar nossa classe assim:


public class VisualizadorDeFoto extends AppCompatActivity {

protected void onCreate(Bundle bundle) { 
 super.onCreate(bundle); 
 setContentView(R.layout.activity_visualizador);

ImageView campoFoto = (ImageView) findViewById(R.id.campoFoto);
Bitmap bitmap = CarregadorDeFoto.carrega("foto_supimpa.jpg"); 
campoFoto.setImageBitmap(bitmap); }

}

Agora sim já podemos mostrar nossas fotos sem se preocupar se elas foram tiradas com o celular de pé ou de lado!

O que você achou dessa dica? Também já passou por esse problema e resolveu de outro jeito? Conta pra gente!

Se você quer evoluir no desenvolvimento mobile, chegou o momento ideal: estão abertas as inscrições para a Imersão Mobile da Alura!

De 14 a 16 de abril, você vai aprender a desenvolver um app de delivery para Android e iOS com Flutter. Serão três aulas 100% práticas, onde cada etapa te leva para um novo nível de conhecimento, te ajudando a consolidar habilidades essenciais para sua carreira.

Aprenda com especialistas do mercado, encare desafios reais e crie um projeto prático, colocando a mão na massa desde o primeiro dia. Evento 100% gratuito! Inscreva-se agora neste link.

Você também pode dar uma olhadinha nos cursos mobile do Alura ou nos cursos presenciais da Caelum!

Veja outros artigos sobre Mobile