Quando carrego uma imagem da galeria de mídia em um Bitmap, tudo está funcionando bem, exceto que as fotos tiradas com a câmera enquanto segura o telefone na vertical são giradas para que eu sempre tenha uma imagem horizontal, mesmo que pareça vertical na tela. galeria. Por que isso e como posso carregá-lo corretamente?
138
Respostas:
Você já viu os dados EXIF das imagens? Pode saber a orientação da câmera quando a foto foi tirada.
fonte
Então, como exemplo ...
Primeiro, você precisa criar um ExifInterface:
Você pode pegar a orientação da imagem:
Aqui está o que os valores de orientação significam: http://sylvana.net/jpegcrop/exif_orientation.html
Portanto, os valores mais importantes são 3, 6 e 8. Se a orientação for
ExifInterface.ORIENTATION_ROTATE_90
(que é 6), por exemplo, você pode girar a imagem da seguinte maneira:Esse é apenas um exemplo rápido, no entanto. Tenho certeza de que existem outras maneiras de executar a rotação real. Mas você também encontrará no StackOverflow.
fonte
OutOfMemoryError
ao usar essa abordagem ao manter dois bitmaps na memória ao mesmo tempo.Esta é uma solução completa (encontrada no exemplo Hackbook do Facebook SDK). Tem a vantagem de não precisar de acesso ao próprio arquivo. Isso é extremamente útil se você estiver carregando uma imagem do resolvedor de conteúdo (por exemplo, se seu aplicativo estiver respondendo a uma intenção de compartilhar fotos).
E então você pode obter um Bitmap girado da seguinte maneira. Esse código também reduz a imagem (infelizmente) para MAX_IMAGE_DIMENSION. Caso contrário, você pode ficar sem memória.
fonte
ExifInterface exif = new ExifInterface(photoUri.getPath());
e, em seguida,exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1)
para obter orientação (por exemploORIENTATION_ROTATE_90
,ORIENTATION_ROTATE_180
)Resolvi no meu caso com esse código usando a ajuda deste post:
Espero que economize o tempo de alguém!
fonte
Use um utilitário para fazer o levantamento pesado.
A 9re criou um utilitário simples para lidar com o trabalho pesado de lidar com dados EXIF e girar imagens para a orientação correta.
Você pode encontrar o código do utilitário aqui: https://gist.github.com/9re/1990019
Simplesmente faça o download, adicione-o ao
src
diretório do seu projeto e use-oExifUtil.rotateBitmap()
para obter a orientação correta, assim:fonte
é porque a galeria correta exibindo imagens rotacionadas, mas não o ImageView, veja aqui:
e você precisa disso:
fonte
Consegui funcionar depois de muitas tentativas graças a um post que não consigo mais encontrar :-(
Exif parece funcionar sempre, a dificuldade era obter o caminho do arquivo. O código que encontrei torna diferente entre a API anterior a 4.4 e posterior à 4.4. Basicamente, o URI da imagem para 4.4+ contém "com.android.providers". Para esse tipo de URI, o código usa o DocumentsContract para obter a identificação da imagem e, em seguida, executa uma consulta usando o ContentResolver, enquanto no SDK antigo, o código segue diretamente para consultar o URI com o ContentResolver.
Aqui está o código (desculpe, não posso creditar quem o postou):
fonte
Você pode simplesmente ler o caminho do cartão SD e fazer o seguinte código ... Ele substituirá a foto existente depois de girá-la.
Não: o Exif não funciona na maioria dos dispositivos, fornece dados incorretos, portanto, é bom codificar a rotação antes de salvar na medida que você desejar, basta alterar o valor do ângulo no postRotate para o desejado.
fonte
Código Kotlin:
fonte
Eu melhorei com a resposta de Teo Inke. Ele não gira mais a imagem, a menos que seja realmente necessário. Também é mais fácil de ler e deve correr mais rápido.
fonte
A primeira coisa que você precisa é o caminho real do arquivo. Se você o possui, se estiver usando o URI, use este método para obter o caminho real:
extraia seu Bitmap, por exemplo:
você pode usar decodeFile (), se desejar.
Agora que você tem o Bitmap e o caminho real, obtenha a orientação da imagem:
e, finalmente, gire-o para a posição correta da seguinte maneira:
É isso, agora você tem o bitmap girado para a posição correta.
Felicidades.
fonte
Isso funciona, mas provavelmente não é a melhor maneira de fazê-lo, mas pode ajudar alguém.
fonte
talvez isso ajude (gire 90 graus) (funcionou para mim)
fonte
O cursor deve ser fechado após abri-lo.
Aqui está um exemplo.
fonte
Derreti a resposta @Timmmm e @Manuel. Se você fizer essa solução, não receberá uma exceção de falta de memória.
Este método recupera a orientação da imagem:
Portanto, você usaria esse método para redimensionar a imagem antes de carregá-la na memória. Dessa forma, você não receberá uma exceção de memória.
Isso funciona perfeitamente para mim. Espero que isso ajude outra pessoa
fonte
Melhorando a solução acima da Timmmm para adicionar uma escala extra no final para garantir que a imagem caiba dentro dos limites:
fonte
Use o seguinte código para girar uma imagem corretamente:
fonte
Os métodos abaixo dimensionam AND gira o bitmap de acordo com a orientação:
Exemplo:
fonte
Resolvi o problema com a seguinte solução alternativa. Observe que também estou dimensionando a imagem, necessária para evitar OutOfMemoryExceptions.
Lembre-se de que esta solução não funcionará corretamente com imagens de retrato ou de cabeça para baixo (obrigado Timmmm pela observação). A solução da Timmmm acima pode ser a melhor escolha se for necessário e também parecer mais elegante: https://stackoverflow.com/a/8914291/449918
Felicidades
fonte