Estou capturando uma imagem e configurando-a para visualização de imagem.
public void captureImage() {
Intent intentCamera = new Intent("android.media.action.IMAGE_CAPTURE");
File filePhoto = new File(Environment.getExternalStorageDirectory(), "Pic.jpg");
imageUri = Uri.fromFile(filePhoto);
MyApplicationGlobal.imageUri = imageUri.getPath();
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intentCamera, TAKE_PICTURE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intentFromCamera) {
super.onActivityResult(requestCode, resultCode, intentFromCamera);
if (resultCode == RESULT_OK && requestCode == TAKE_PICTURE) {
if (intentFromCamera != null) {
Bundle extras = intentFromCamera.getExtras();
if (extras.containsKey("data")) {
bitmap = (Bitmap) extras.get("data");
}
else {
bitmap = getBitmapFromUri();
}
}
else {
bitmap = getBitmapFromUri();
}
// imageView.setImageBitmap(bitmap);
imageView.setImageURI(imageUri);
}
else {
}
}
public Bitmap getBitmapFromUri() {
getContentResolver().notifyChange(imageUri, null);
ContentResolver cr = getContentResolver();
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, imageUri);
return bitmap;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
Mas o problema é que a imagem em alguns dispositivos toda vez que é rotacionada. Por exemplo, em um dispositivo Samsung, ele funciona bem, mas em um Sony Xperia a imagem é girada em 90 graus e no Toshiba Thrive (tablet) em 180 graus.
Respostas:
A maioria das câmeras de telefone é horizontal, ou seja, se você tirar a foto em retrato, as fotos resultantes serão giradas 90 graus. Nesse caso, o software da câmera deve preencher os dados Exif com a orientação em que a foto deve ser exibida.
Observe que a solução abaixo depende do fabricante do software / dispositivo da câmera que preenche os dados Exif; portanto, ele funciona na maioria dos casos, mas não é uma solução 100% confiável.
Aqui está o
rotateImage
método:fonte
exif.getAttributeInt
usoExifInterface.ORIENTATION_UNDEFINED
é quase a mesma, pois o segundo parâmetro é o valor padrão, caso a função falhe em fornecer o valor.Ao combinar Jason Robinson 's resposta com Felix ' s resposta e preencher as partes em falta, aqui é a solução completa final para esta questão que irá fazer o seguinte após testá-lo no Android Android 4.1 ( Jelly Bean ), Android 4.4 ( KitKat ) e Android 5.0 ( pirulito ).
Passos
Diminua a imagem se ela for maior que 1024x1024.
Gire a imagem para a orientação correta somente se estiver girando 90, 180 ou 270 graus.
Recicle a imagem girada para fins de memória.
Aqui está a parte do código:
Chame o método a seguir com a atual
Context
e a imagemURI
que deseja corrigirAqui está o
CalculateInSampleSize
método da fonte mencionada anteriormente :Depois, vem o método que verifica a orientação atual da imagem para decidir o ângulo de rotação
Finalmente, o próprio método de rotação
-Não se esqueça de votar nas respostas desses caras por seus esforços e em Shirish Herwade, que fez essa pergunta útil.
fonte
É fácil detectar a orientação da imagem e substituir o bitmap usando:
Para evitar a falta de memórias com imagens grandes, recomendo que você redimensione a imagem usando:
Não é possível usar o ExifInterface para obter a orientação devido a um problema no sistema operacional Android: https://code.google.com/p/android/issues/detail?id=19268
E aqui está
calculateInSampleSize
fonte
Solução de uma linha:
Ou
Isso detecta automaticamente a rotação e coloca a imagem na orientação correta
O Picasso é uma biblioteca muito poderosa para manipular imagens no seu aplicativo: Transformações complexas de imagens com uso mínimo de memória.
fonte
Passei muito tempo procurando soluções para isso. E finalmente conseguiu fazer isso. Não esqueça de votar em @Jason Robinson, porque o meu é baseado no dele.
Então, primeiro, você deve saber que, desde o Android 7.0, precisamos usar
FileProvider
algo chamadoContentUri
, caso contrário, você receberá um erro irritante ao tentar invocar o seuIntent
. Este é um código de exemplo:Método
getUriFromPath(Context, String)
baseado na versão do usuário do Android createFileUri (file://...)
ouContentUri (content://...)
e lá está:Depois de
onActivityResult
capturar o localuri
onde a imagem é salva pela câmera, mas agora você precisa detectar a rotação da câmera, aqui usaremos a resposta modificada de @Jason Robinson:Primeiro precisamos criar com
ExifInterface
base emUri
O código acima pode ser simplificado, mas quero mostrar tudo. Então
FileUri
, podemos criar comExifInterface
baseString path
, masContentUri
não podemos, o Android não suporta isso.Nesse caso, temos que usar outro construtor baseado em
InputStream
. Lembre-se de que este construtor não está disponível por padrão, você deve adicionar uma biblioteca adicional:Agora podemos usar o
getExifInterface
método para obter nosso ângulo:Agora você tem Angle para girar corretamente sua imagem :).
fonte
activity_main.xml
MainActivity.java
fonte
Você pode ler a orientação do sensor da câmera conforme indicado pelo Google na documentação: https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html
Código de amostra:
fonte
Jason Robinson resposta e Sami Eltamawy resposta são excelentes.
Apenas uma melhoria para concluir a abordagem, você deve usar compat ExifInterface.
com.android.support:exifinterface:${lastLibVersion}
Você poderá instanciar o ExifInterface (pior API <24) com caminhos
InputStream
(fromContentResolver
) em vez de uri, evitando "Arquivo não encontrado exceções"https://android-developers.googleblog.com/2016/12/introducing-the-exifinterface-support-library.html
fonte
Normalmente, é recomendável resolver o problema com o ExifInterface , como sugeriu @Jason Robinson. Se essa abordagem não funcionar, tente procurar a orientação da última imagem tirada ...
fonte
Infelizmente, a resposta @ jason-robinson acima não funcionou para mim.
Embora a função de rotação funcione perfeitamente:
Eu tive que fazer o seguinte para obter a orientação, pois a orientação Exif sempre foi 0
fonte
Melhor tentar tirar a foto em uma orientação específica.
Para obter melhores resultados, forneça orientação de paisagem na atividade de visualização de câmera.
fonte
Se experiências alguém problemas com
ExifInterface
on Android 4.4 (KitKat) para obter a orientação, pode ser por causa de errado caminho obteve da URI. Veja uma solução para propoergetPath
na pergunta Stack Overflow Obtenha o caminho real a partir do URI, Android KitKat nova estrutura de acesso ao armazenamentofonte
Encontre abaixo o link desta solução é a melhor https://www.samieltamawy.com/how-to-fix-the-camera-intent-rotated-image-in-android/
fonte
A resposta selecionada usa o método mais comum respondido a esta e a perguntas semelhantes. No entanto, ele não funciona com as câmeras frontal e traseira da Samsung. Para quem procura uma solução que funcione nas câmeras frontal e traseira da Samsung e de outros grandes fabricantes, a resposta da nvhausid é impressionante:
https://stackoverflow.com/a/18915443/6080472
Para aqueles que não querem clicar, a mágica relevante é usar o CameraInfo em vez de confiar no EXIF.
Código completo no link.
fonte
Talvez isso seja óbvio, mas lembre-se sempre de que você pode lidar com alguns desses problemas de manipulação de imagem no servidor. Usei respostas como as contidas neste tópico para lidar com a exibição imediata da imagem. No entanto, meu aplicativo exige que as imagens sejam armazenadas no servidor (esse é provavelmente um requisito comum se você deseja que a imagem persista enquanto os usuários trocam de telefone).
As soluções contidas em muitos dos tópicos relacionados a este tópico não discutem a falta de persistência dos dados EXIF que não sobrevivem à compactação de imagem do Bitmap, o que significa que você precisará girar a imagem cada vez que o servidor a carregar. Como alternativa, você pode enviar os dados de orientação EXIF para o servidor e, em seguida, girar a imagem para lá, se necessário.
Era mais fácil para mim criar uma solução permanente em um servidor porque não precisava me preocupar com os caminhos de arquivos clandestinos do Android.
fonte
A solução mais simples para esse problema:
Estou salvando a imagem em formato jpg.
fonte
Aqui está a
Xamarin.Android
versão:Da resposta de @Jason Robinson :
Então
calculateInSampleSize
método:Da resposta de @Sami Eltamawy :
fonte
Se você estiver usando o Fresco, poderá usar isto -
Isso gira automaticamente as imagens com base nos dados Exif.
Fonte: https://frescolib.org/docs/rotation.html
fonte
O código abaixo trabalhou comigo, ele obteve o bitmap do fileUri e, se necessário, corrige a rotação:
fonte
Tem uma resposta para esse problema sem usar o ExifInterface . Podemos obter a rotação da câmera frontal ou traseira, independentemente do que você estiver usando. Ao criar o Bitmap, podemos girar o bitmap usando Matrix.postRotate (degree)
Depois de calcular a rotação, você pode girar seu bitmap como abaixo:
Herare bm deve ser seu bitmap.
Se você quiser saber a rotação da sua câmera frontal, basta alterar Camera.CameraInfo.CAMERA_FACING_BACK para Camera.CameraInfo.CAMERA_FACING_FRONT acima.
Eu espero que isso ajude.
fonte
Criei uma função de extensão Kotlin que simplifica a operação para desenvolvedores Kotlin com base na resposta de @Jason Robinson. Espero que ajude.
fonte
Existe um comando mais simples para corrigir esse erro.
Basta adicionar depois do yourImageView.setBitmap (bitmap); this yourImageView.setRotation (90);
Este meu fixo. Espero que ajude !
fonte
isso funcionou para mim
fonte