2015-08-10 13 views
22

Sto tentando di consentire agli utenti di selezionare un'immagine del profilo dalla galleria. Il mio problema è che alcune immagini vengono ruotate a destra.Viene prelevata un'immagine Android dalla galleria ruotata

comincio l'immagine picker in questo modo:

Intent photoPickerIntent = new Intent(); 
photoPickerIntent.setType("image/*"); 
photoPickerIntent.setAction(Intent.ACTION_GET_CONTENT); 
startActivityForResult(Intent.createChooser(photoPickerIntent, "Select profile picture"), Global.CODE_SELECT_PICTURE); 

ho l'immagine da onActivityResult in questo modo:

Uri selectedPicture = data.getData(); 
profilePic = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), selectedPicture); 

Come posso fare non sono immagini per essere ruotato?

UPDATE:

seguito alcune delle risposte che ho ricevuto, sono riuscito a venire con la seguente soluzione di lavoro (E 'solo un codice di lavoro, non è ben scritto). Mi piacerebbe avere il tuo feedback su come posso migliorarlo!

public void onActivityResult(int requestCode, int resultCode, Intent data) { 

    if (resultCode == Activity.RESULT_OK && requestCode == Global.CODE_SELECT_PICTURE) { 

     // Get selected gallery image 
     Uri selectedPicture = data.getData(); 
     // Get and resize profile image 
     String[] filePathColumn = {MediaStore.Images.Media.DATA}; 
     Cursor cursor = activity.getContentResolver().query(selectedPicture, filePathColumn, null, null, null); 
     cursor.moveToFirst(); 

     int columnIndex = cursor.getColumnIndex(filePathColumn[0]); 
     String picturePath = cursor.getString(columnIndex); 
     cursor.close(); 

     Bitmap loadedBitmap = BitmapFactory.decodeFile(picturePath); 

     ExifInterface exif = null; 
     try { 
      File pictureFile = new File(picturePath); 
      exif = new ExifInterface(pictureFile.getAbsolutePath()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     int orientation = ExifInterface.ORIENTATION_NORMAL; 

     if (exif != null) 
      orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 

     switch (orientation) { 
      case ExifInterface.ORIENTATION_ROTATE_90: 
       loadedBitmap = rotateBitmap(loadedBitmap, 90); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_180: 
       loadedBitmap = rotateBitmap(loadedBitmap, 180); 
       break; 

      case ExifInterface.ORIENTATION_ROTATE_270: 
       loadedBitmap = rotateBitmap(loadedBitmap, 270); 
       break; 
     }   
    } 
} 

public static Bitmap rotateBitmap(Bitmap bitmap, int degrees) { 
    Matrix matrix = new Matrix(); 
    matrix.postRotate(degrees); 
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
} 
+0

la soluzione funziona su ogni software/dispositivo? Sto affrontando lo stesso problema ... – tsiro

+0

grazie. ha funzionato come un incantesimo..le risposte in basso non funzionano nel mio caso .. –

+0

[Questo] (https://stackoverflow.com/a/8914291/1911652) ottiene bitmap dall'URI con l'orientamento corretto – Atul

risposta

21

Si potrebbe utilizzare ExifInterface per modificare l'orientamento:

public static Bitmap modifyOrientation(Bitmap bitmap, String image_absolute_path) throws IOException { 
    ExifInterface ei = new ExifInterface(image_absolute_path); 
    int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 

    switch (orientation) { 
    case ExifInterface.ORIENTATION_ROTATE_90: 
     return rotate(bitmap, 90); 

    case ExifInterface.ORIENTATION_ROTATE_180: 
     return rotate(bitmap, 180); 

    case ExifInterface.ORIENTATION_ROTATE_270: 
     return rotate(bitmap, 270); 

    case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: 
     return flip(bitmap, true, false); 

    case ExifInterface.ORIENTATION_FLIP_VERTICAL: 
     return flip(bitmap, false, true); 

    default: 
     return bitmap; 
    } 
} 

public static Bitmap rotate(Bitmap bitmap, float degrees) { 
    Matrix matrix = new Matrix(); 
    matrix.postRotate(degrees); 
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
} 

public static Bitmap flip(Bitmap bitmap, boolean horizontal, boolean vertical) { 
    Matrix matrix = new Matrix(); 
    matrix.preScale(horizontal ? -1 : 1, vertical ? -1 : 1); 
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
} 

Al fine di ottenere il percorso assoluto delle immagini dai loro uri, controllare this answer soluzioni

+0

funziona come un fascino –

+0

ho OutOfMemoryError con questa soluzione –

+0

La risposta che hai indicato per ottenere il percorso assoluto dell'immagine da uri è un'idea MALE. Uno non dovrebbe farlo. Riferisci il commento di CommonsWare sulla risposta. – Atul

3

lo faccio in questo modo:

public void browseClick(View view) { 
    view.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.button_animation)); 
    Intent i = new Intent(
      Intent.ACTION_PICK, 
      android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 

    startActivityForResult(i, RESULT_LOAD_IMAGE); 
} 

E il risultato in cui l'orientamento è verificata vi interesserà più:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) { 
     Uri selectedImage = data.getData(); 
     String[] filePathColumn = { MediaStore.Images.Media.DATA }; 

     Cursor cursor = getContentResolver().query(selectedImage, 
       filePathColumn, null, null, null); 
     cursor.moveToFirst(); 

     int columnIndex = cursor.getColumnIndex(filePathColumn[0]); 
     String picturePath = cursor.getString(columnIndex); 
     cursor.close(); 

     Bitmap loadedBitmap = BitmapFactory.decodeFile(picturePath); 

     Matrix matrix = new Matrix(); 
     Bitmap scaledBitmap; 
     if (loadedBitmap.getWidth() >= loadedBitmap.getHeight()){ 
      matrix.setRectToRect(new RectF(0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight()), new RectF(0, 0, 400, 300), Matrix.ScaleToFit.CENTER); 
      scaledBitmap = Bitmap.createBitmap(loadedBitmap, 0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight(), matrix, true); 
     } else{ 
      matrix.setRectToRect(new RectF(0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight()), new RectF(0, 0, 300, 400), Matrix.ScaleToFit.CENTER); 
      scaledBitmap = Bitmap.createBitmap(loadedBitmap, 0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight(), matrix, true); 
     } 

     File file = new File(getExternalCacheDir(), "image.jpg"); 
     try { 
      FileOutputStream out = new FileOutputStream(file); 
      scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); 
      out.flush(); 
      out.close(); 
     } catch (Exception e) { 
      Log.e("Image", "Convert"); 
     } 

     imageView.setImageBitmap(scaledBitmap); 
    } 
} 
3

io uso questi metodi statici. Il primo determina l'orientamento e il secondo ruota l'immagine riducendola secondo necessità.

public static int getOrientation(Context context, Uri photoUri) { 

    Cursor cursor = context.getContentResolver().query(photoUri, 
      new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); 

    if (cursor == null || cursor.getCount() != 1) { 
     return 90; //Assuming it was taken portrait 
    } 

    cursor.moveToFirst(); 
    return cursor.getInt(0); 
} 

/** 
* Rotates and shrinks as needed 
*/ 
public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri, int maxWidth) 
       throws IOException { 

      InputStream is = context.getContentResolver().openInputStream(photoUri); 
      BitmapFactory.Options dbo = new BitmapFactory.Options(); 
      dbo.inJustDecodeBounds = true; 
      BitmapFactory.decodeStream(is, null, dbo); 
      is.close(); 


      int rotatedWidth, rotatedHeight; 
      int orientation = getOrientation(context, photoUri); 

      if (orientation == 90 || orientation == 270) { 
       Log.d("ImageUtil", "Will be rotated"); 
       rotatedWidth = dbo.outHeight; 
       rotatedHeight = dbo.outWidth; 
      } else { 
       rotatedWidth = dbo.outWidth; 
       rotatedHeight = dbo.outHeight; 
      } 

      Bitmap srcBitmap; 
      is = context.getContentResolver().openInputStream(photoUri); 
      Log.d("ImageUtil", String.format("rotatedWidth=%s, rotatedHeight=%s, maxWidth=%s", 
        rotatedWidth, rotatedHeight, maxWidth)); 
      if (rotatedWidth > maxWidth || rotatedHeight > maxWidth) { 
       float widthRatio = ((float) rotatedWidth)/((float) maxWidth); 
       float heightRatio = ((float) rotatedHeight)/((float) maxWidth); 
       float maxRatio = Math.max(widthRatio, heightRatio); 
       Log.d("ImageUtil", String.format("Shrinking. maxRatio=%s", 
         maxRatio)); 

       // Create the bitmap from file 
       BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inSampleSize = (int) maxRatio; 
       srcBitmap = BitmapFactory.decodeStream(is, null, options); 
      } else { 
       Log.d("ImageUtil", String.format("No need for Shrinking. maxRatio=%s", 
         1)); 

       srcBitmap = BitmapFactory.decodeStream(is); 
       Log.d("ImageUtil", String.format("Decoded bitmap successful")); 
      } 
      is.close(); 

     /* 
     * if the orientation is not 0 (or -1, which means we don't know), we 
     * have to do a rotation. 
     */ 
      if (orientation > 0) { 
       Matrix matrix = new Matrix(); 
       matrix.postRotate(orientation); 

       srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), 
         srcBitmap.getHeight(), matrix, true); 
      } 

      return srcBitmap; 
     } 
+0

Si consiglia di rimuovere il registro .d richiede versioni di produzione. –

0

2 una linea utilizzando Picasso e glide library

Dopo aver trascorso molto tempo con un sacco di solu soluzioni per il problema della rotazione dell'immagine Finalmente ho trovato due soluzioni semplici. Non abbiamo bisogno di fare ulteriori lavori.

Utilizzando biblioteca Picassohttps://github.com/square/picasso

Picasso.with(context).load("http url or sdcard url").into(imageView); 

Utilizzando libreria glidehttps://github.com/bumptech/glide

Glide.with(this).load("http url or sdcard url").into(imgageView); 

Picasso e Glide sono una libreria molto potente per la gestione delle immagini nella vostra applicazione include. Legge i dati EXIF ​​dell'immagine e ruota automaticamente le immagini.

Problemi correlati