2016-06-27 11 views
5

Ich habe eine Methode Bilder zu drehen, aber ich habe immer eine OutMemoryError erhalten, aber meine Bilder in der Galerie iare von der Kamera aufgenommen und Größe Breite ist 5000 ~ von TelefonAndroid Bild der Größe neu Fehlerspeicher

I Foto verkleinerte 1280 Breite und Höhe 960

mein erstes Verfahren für die Show und die Größe Bild ist

public static Boolean ShowImagesCapture(Context context, Uri PATH_IMAGE, ImageCropView view,int width, int height){ 

    int orientation=0; 
    Boolean success = true; 
    try { 
     Bitmap bitmap =null; 

     if (Build.VERSION.SDK_INT < 19) { 
      String selectedImagePath = getPath(PATH_IMAGE,context); 
      bitmap = BitmapFactory.decodeFile(selectedImagePath); 
      orientation=GetPhotoOrientation(context,getRealPathFromURI(context,PATH_IMAGE)); 
     } 

     else { 
      ParcelFileDescriptor parcelFileDescriptor; 

      try { 
       parcelFileDescriptor = context.getContentResolver().openFileDescriptor(PATH_IMAGE, "r"); 
       FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); 
       bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor); 
       parcelFileDescriptor.close(); 
       orientation=GetPhotoOrientation(context,getRealPathFromURI(context,PATH_IMAGE)); 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
     switch (orientation) { 

      case ExifInterface.ORIENTATION_ROTATE_180: 
       bitmap=rotateBitmap(bitmap,3,width,height); 
       view.setImageBitmap(bitmap); 

       break; 
     break; 
      case ExifInterface.ORIENTATION_ROTATE_90: 
       bitmap=rotateBitmap(bitmap,8,width,height); 
       view.setImageBitmap(bitmap); 
       break; 

      case ExifInterface.ORIENTATION_TRANSVERSE: 
       break; 

      case ExifInterface.ORIENTATION_ROTATE_270: 
       bitmap=rotateBitmap(bitmap,6,width,height); 
       view.setImageBitmap(bitmap); 
       break; 

      default: 
       view.setImageBitmap(bitmap); 

     } 

     bitmap = null; 

    } 
    catch (Exception e) { 
     e.printStackTrace(); 
     success= false; 
    } 
    System.gc(); 
    return success; 
} 

und meine Methode zum drehen Bild ist

public static Bitmap rotateBitmap(Bitmap bitmap, int orientation,int width,int height) { 

    try { 
     Matrix matrix = new Matrix(); 
     switch (orientation) { 
      case ExifInterface.ORIENTATION_NORMAL: 
       return bitmap; 
      case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: 
       //    matrix.setScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_180: 
       matrix.setRotate(180); 
       break; 
      case ExifInterface.ORIENTATION_FLIP_VERTICAL: 
       matrix.setRotate(180); 
       //    matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_TRANSPOSE: 
       matrix.setRotate(90); 
       //    matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_90: 
       matrix.setRotate(90); 
       break; 
      case ExifInterface.ORIENTATION_TRANSVERSE: 
       matrix.setRotate(-90); 
       //    matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_270: 
       matrix.setRotate(-270); 
       break; 
      default: 
       return bitmap; 
     } 



     Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false); 
     bitmap.recycle(); 
     return bmRotated; 

    } 
    catch (OutOfMemoryError e) { 
     Log.e(TAG,"Out memory Error"); 
     return null; 
    }catch (Exception e){ 
     e.printStackTrace(); 
     return null; 
    } 
} 

wo ist mein Fehler?

* ------------------- ** UPDATE 27. Juni 2016 ** ------------------ - *

MEIN CODE haben eine beste Version adaequat

public static Bitmap rotateBitmap(Bitmap bitmap, int orientation,int width,int height) { 

    try { 
     Matrix matrix = new Matrix(); 
     switch (orientation) { 
      case ExifInterface.ORIENTATION_NORMAL: 
       return bitmap; 
      case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: 
       matrix.setScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_180: 
       matrix.setRotate(180); 
       break; 
      case ExifInterface.ORIENTATION_FLIP_VERTICAL: 
       matrix.setRotate(180); 
       matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_TRANSPOSE: 
       matrix.setRotate(90); 
       matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_90: 
       matrix.setRotate(90); 
       break; 
      case ExifInterface.ORIENTATION_TRANSVERSE: 
       matrix.setRotate(-90); 
       matrix.postScale(-1, 1); 
       break; 
      case ExifInterface.ORIENTATION_ROTATE_270: 
       matrix.setRotate(-270); 
       break; 
      default: 
       return bitmap; 
     } 
     Bitmap bmRotated= null; 
     try { 
      Bitmap tmp_bitmap= Bitmap.createScaledBitmap(bitmap,width,height,true); 

      bmRotated = Bitmap.createBitmap(tmp_bitmap, 0, 0, tmp_bitmap.getWidth(),tmp_bitmap.getHeight(), matrix, true); 

      bitmap.recycle(); 
     }catch (OutOfMemoryError e){ 
      e.printStackTrace(); 
     } 
     return bmRotated; 

    } catch (Exception e){ 
     e.printStackTrace(); 
     return null; 
    } 
} 


public static Bitmap decodefilebitmap(String selectedImagePath, int reqWidth, int reqHeight) { 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(selectedImagePath, options); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeFile(selectedImagePath, options); 
} 

public static int calculateInSampleSize(
     BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     final int halfHeight = height/2; 
     final int halfWidth = width/2; 

     // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
     // height and width larger than the requested height and width. 
     while ((halfHeight/inSampleSize) > reqHeight 
       && (halfWidth/inSampleSize) > reqWidth) { 
      inSampleSize *= 2; 
     } 
    } 

    return inSampleSize; 
} 

//METODO PARA MOSTRAR LA IMAGEN DESDE LA GALERIA 
public static Boolean ShowImagesCapture(Context context, Uri PATH_IMAGE, ImageCropView view,int width, int height){ 

    int orientation=0; 
    Boolean success = true; 
    try { 
     Bitmap bitmap =null; 
     BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 

     if (Build.VERSION.SDK_INT < 19) { 
      String selectedImagePath = getPath(PATH_IMAGE,context); 
      bitmap = decodefilebitmap(selectedImagePath,bitmap.getWidth(),bitmap.getHeight()); 
      orientation=GetPhotoOrientation(context,getRealPathFromURI(context,PATH_IMAGE)); 
     } 

     else { 
      ParcelFileDescriptor parcelFileDescriptor; 

      try { 
       parcelFileDescriptor = context.getContentResolver().openFileDescriptor(PATH_IMAGE, "r"); 
       FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); 
       bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor); 
       parcelFileDescriptor.close(); 
       orientation=GetPhotoOrientation(context,getRealPathFromURI(context,PATH_IMAGE)); 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
     switch (orientation) { 


      case ExifInterface.ORIENTATION_ROTATE_180: 
       bitmap=rotateBitmap(bitmap,3,width,height); 
       view.setImageBitmap(bitmap); 

       break; 

      case ExifInterface.ORIENTATION_ROTATE_90: 
       bitmap=rotateBitmap(bitmap,8,width,height); 
       view.setImageBitmap(bitmap); 
       break; 

      case ExifInterface.ORIENTATION_TRANSVERSE: 
       break; 

      case ExifInterface.ORIENTATION_ROTATE_270: 
       bitmap=rotateBitmap(bitmap,6,width,height); 
       view.setImageBitmap(bitmap); 
       break; 

      default: 
       view.setImageBitmap(bitmap); 

     } 

     bitmap = null; 

    } 
    catch (Exception e) { 
     e.printStackTrace(); 
     success= false; 
    } 
    System.gc(); 
    return success; 
} 

Antwort

3

das ist, weil Sie die ganze Bitmap in den Speicher bitmap = BitmapFactory.decodeFile(selectedImagePath); geladen werden und dann eine Größe veränderte Version in die Image zeigt (aber verschwenden Speicher, weil der komplette haben Größe Version im RAM). Sie müssen eine verkleinerte Version laden. Es ist nicht dasselbe, alle Bitmap-Dateien zu laden und dann Operationen auszuführen (skalieren, drehen, in eine Bildansicht einfügen), als eine verkleinerte Version dieser Bitmap in den Speicher zu laden. Wenn Sie beispielsweise ein Bild mit 5000 mal 5000 Pixeln haben, nehmen Sie an, dass die Größe im JPEG-Format etwa 1 MB beträgt. Aber wenn Sie es in den Speicher laden, dekomprimieren Sie es und laden Sie die ganze unkomprimierte Version dieses Bildes. Angenommen, Sie laden es in 32 Bit pro Pixel, dann wäre seine Größe im RAM 5000x5000x32 Bit, das sind etwa 95 MB! Sie müssen also eine verkleinerte Version laden. Sehen Sie sich dieses Android-Entwicklerdokument about loading a scaled down bitmap version into memory an. Das wird dir helfen, das Problem besser zu verstehen. Sie können auch Bildladebibliotheken wie Glide verwenden. Diese Bibliotheken machen all dies und noch mehr.

+0

ja und .. Verfahren drehen Bild erstes Bild für niedrige Bildbreite und -höhe und nach drehen Bild durch die Größe! – pedroooo

+0

Ich aktualisiere auf Lösung für Code !! Grüße – pedroooo

+0

@pedroooo Kein Problem, froh, dass ich dir geholfen habe =). – josemgu91