Je construis une application qui utilise l'appareil photo pour prendre des photos. Voici mon code source pour le faire:
File file = new File(Environment.getExternalStorageDirectory(),
imageFileName);
imageFilePath = file.getPath();
Intent intent = new Intent("Android.media.action.IMAGE_CAPTURE");
//Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, ACTIVITY_NATIVE_CAMERA_AQUIRE);
Sur la méthode onActivityResult()
, j'utilise BitmapFactory.decodeStream()
pour prendre l'image.
Lorsque je lance mon application sur Nexus one, elle fonctionne bien. Mais lorsque je suis sur Samsung Galaxy S ou HTC Inspire 4G, la direction de l'image n'est pas correcte.
Aperçu de l'image après la prise de vue --------- Image réelle sur la carte SD
Aperçu de l'image après la prise de vue --------- Image réelle sur la carte SD
Il y a pas mal de sujets et de problèmes similaires ici. Puisque vous n'écrivez pas votre propre caméra, je pense que cela se résume à ceci:
certains périphériques font pivoter l'image avant de l'enregistrer, tandis que d'autres ajoutent simplement la balise d'orientation dans les données exif de la photo.
Je vous recommande de vérifier les données exif de la photo et de rechercher en particulier
ExifInterface exif = new ExifInterface(SourceFileName); //Since API Level 5
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
Étant donné que la photo s'affiche correctement dans votre application, je ne suis pas sûr du problème, mais cela devrait vous mettre sur la bonne voie!
Je viens de rencontrer le même problème et je l’ai utilisé pour corriger l’orientation:
public void fixOrientation() {
if (mBitmap.getWidth() > mBitmap.getHeight()) {
Matrix matrix = new Matrix();
matrix.postRotate(90);
mBitmap = Bitmap.createBitmap(mBitmap , 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
}
}
Si la largeur du bitmap est supérieure à la hauteur, l'image renvoyée est en mode paysage, je la fais donc pivoter de 90 degrés.
J'espère que cela aidera quelqu'un d'autre avec ce problème.
Il y a deux choses nécessaires:
L'aperçu de la caméra doit être identique à votre rotation. Définissez ceci par camera.setDisplayOrientation(result);
Enregistrez l'image capturée en tant qu'aperçu de votre caméra. Faites ceci via Camera.Parameters
.
int mRotation = getCameraDisplayOrientation();
Camera.Parameters parameters = camera.getParameters();
parameters.setRotation(mRotation); //set rotation to save the picture
camera.setDisplayOrientation(result); //set the rotation for preview camera
camera.setParameters(parameters);
J'espère que ça t'as aidé.
int rotate = 0;
try {
File imageFile = new File(sourcepath);
ExifInterface exif = new ExifInterface(
imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (Exception e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
bitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
Une autre option consiste à faire pivoter le bitmap dans l'écran de résultat comme suit:
ImageView img=(ImageView)findViewById(R.id.ImageView01);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.refresh);
// Getting width & height of the given image.
int w = bmp.getWidth();
int h = bmp.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true);
BitmapDrawable bmd = new BitmapDrawable(rotatedBMP);
img.setImageDrawable(bmd);
J'ai aussi ce type de problème pour certains appareils:
private void rotateImage(final String path) {
Bitmap scaledBitmap = Bitmap.createScaledBitmap(Conasants.bm1, 1000,
700, true);
Bitmap rotatedBitmap = null;
try {
ExifInterface ei = new ExifInterface(path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate(90);
rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(),
matrix, true);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate(180);
rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(),
matrix, true);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.postRotate(270);
rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(),
matrix, true);
break;
default:
rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(),
matrix, true);
break;
}
} catch (Throwable e) {
e.printStackTrace();
}
cropImage.setImageBitmap(rotatedBitmap);
rotatedBitmap = null;
Conasants.bm1 = null;
}
Plus besoin de vérifier les données exif de la photo. Allez-y doucement avec Glide .
Google nous a présenté une bibliothèque Image Loader pour Android développée par bumptech nommée Glide comme une bibliothèque recommandée par Google. Elle a été utilisé dans de nombreux projets Google open source jusqu'à présent, y compris l'application officielle de Google I/O 2014.
Ex: Glide.with (contexte) .load (uri) .into (imageview);
Pour plus: https://github.com/bumptech/glide
Essayez de cette façon: Uri statique image_uri; static Bitmap taken_image = null;
image_uri=fileUri; // file where image has been saved
taken_image=BitmapFactory.decodeFile(image_uri.getPath());
try
{
ExifInterface exif = new ExifInterface(image_uri.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 270);
break;
case ExifInterface.ORIENTATION_NORMAL:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 0);
break;
}
}
catch (OutOfMemoryError e)
{
Toast.makeText(getActivity(),e+"\"memory exception occured\"",Toast.LENGTH_LONG).show();
}
public Bitmap RotateBitmap(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
round_Image = source;
round_Image = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
public void setCameraPicOrientation(){
int rotate = 0;
try {
File imageFile = new File(mCurrentPhotoPath);
ExifInterface exif = new ExifInterface(
imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (Exception e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
int targetW = 640;
int targetH = 640;
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scaleFactor = 1;
if ((targetW > 0) || (targetH > 0)) {
scaleFactor = Math.min(photoW/targetW, photoH/targetH);
}
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
/* Decode the JPEG file into a Bitmap */
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
bitmap= Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
/* Associate the Bitmap to the ImageView */
imageView.setImageBitmap(bitmap);
}
J'espère que ça va aider !! Merci
deux solutions à une ligne utilisant Picasso et la bibliothèque de plané
Après avoir passé beaucoup de temps avec beaucoup de solutions au problème de rotation d’image, j’ai finalement trouvé deux solutions simples. Nous n'avons pas besoin de faire des travaux supplémentaires. Picasso et Glide constituent une bibliothèque très puissante pour la gestion des images dans votre application. Il lira les données EXIF des images et effectuera une rotation automatique des images.
Utilisation de la bibliothèque de glissement https://github.com/bumptech/glide
Glide.with(this).load("http url or sdcard url").into(imgageView);
Utilisation de la bibliothèque Picasso https://github.com/square/picasso
Picasso.with(context).load("http url or sdcard url").into(imageView);
public static int mOrientation = 1;
OrientationEventListener myOrientationEventListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.takephoto);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
myOrientationEventListener
= new OrientationEventListener(getApplicationContext()) {
@Override
public void onOrientationChanged(int o) {
// TODO Auto-generated method stub
if(!isTablet(getApplicationContext()))
{
if(o<=285 && o>=80)
mOrientation = 2;
else
mOrientation = 1;
}
else
{
if(o<=285 && o>=80)
mOrientation = 1;
else
mOrientation = 2;
}
}
};
myOrientationEventListener.enable();
}
public static boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
}
J'espère que cela aidera.Merci!
Essayez ceci dans le rappel surfaceChanged:
Camera.Parameters parameters=mCamera.getParameters();
if(this.getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
parameters.setRotation(90);
}else{
parameters.setRotation(0);
}
mCamera.setParameters(parameters);
Juste rencontrer le même problème ici, l'extrait de code ci-dessous fonctionne pour moi:
private static final String[] CONTENT_ORIENTATION = new String[] {
MediaStore.Images.ImageColumns.ORIENTATION
};
static int getExifOrientation(ContentResolver contentResolver, Uri uri) {
Cursor cursor = null;
try {
cursor = contentResolver.query(uri, CONTENT_ORIENTATION, null, null, null);
if (cursor == null || !cursor.moveToFirst()) {
return 0;
}
return cursor.getInt(0);
} catch (RuntimeException ignored) {
// If the orientation column doesn't exist, assume no rotation.
return 0;
} finally {
if (cursor != null) {
cursor.close();
}
}
}
espérons que cela aide :)