1

Ich habe eine Menge Dokumentation gefunden, wie große Bitmaps geladen werden und outofmemory Ausnahme zu vermeiden. aber das Problem ist, dass ich das Bild von meinem MediaStore.Images.media zu nehmen, so dass die klassischen decodeFile(path,options) in der Google-Dokumentation angegeben mich nichtoutofmemory Ausnahme für große Bitmap

funktioniert Wie Sie sehen unter mir die Linie // Bitmap photo= Mediastore.Images decommented, dh derjenige, der den nicht ausreichenden Speicher auslöst. auf der anderen Seite die Zeile Bitmap bm=BitmapFactory.decodeFile(selectedImageToUri,options) gibt null zurück, obwohl der Compiler beide den Pfad in selectedImageToUri (die den Inhaltsanbieter angibt, wo die Bilder sind) als die Optionen Wert, den ich auf 8 festgelegt, da ich alle Subskalen die Bilder

Meine Frage ist, wie kann ich in BM die Bitmap einfügen, die sich auf das Bild bezieht, das vom Benutzer in der Galerie ausgewählt wird. in der Zeile BitMap photo gibt nicht Null und funktioniert wirklich gut, aber ich zerlegt, weil, nachdem ich ein paar Bilder ändern gibt mir outofmemory Ausnahme.

@Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable final Bundle savedInstanceState) { 


     if (flagVariable) { 

      if (selectedImageToUri != null) { 


       // BitMap photo = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), Uri.parse(selectedImageToUri)); 


       final BitmapFactory.Options options= new BitmapFactory.Options(); 
       options.inSampleSize=8; 


       Bitmap bm = BitmapFactory.decodeFile(selectedImageToUri, options); 

       pic = new BitmapDrawable(bm); 


       getActivity().getWindow().setBackgroundDrawable(pic); 


      } else { 
       getDefaultImageBackground(inflater, container); 

      } 


      hiddenList = inflater.inflate(R.layout.fragment_as_list_layout_temp, container, false); 

     } else { 
      getDefaultImageBackground(inflater, container); 
     } 

     listView = (ListView) hiddenList.findViewById(R.id.list_hidden); 

Antwort

1

MediaStore.getBitmap nur eine einfache convienence Methode ist, sieht es wie folgt aus:

public static final Bitmap getBitmap(ContentResolver cr, Uri url) 
       throws FileNotFoundException, IOException { 
    InputStream input = cr.openInputStream(url); 
    Bitmap bitmap = BitmapFactory.decodeStream(input); 
    input.close(); 
    return bitmap; 
} 

Sie können Ihre eigene Methode basiert auf dieser erstellen, die die options und ruft eine andere Überlastung BitmapFactory nimmt:

public static final Bitmap getBitmap(ContentResolver cr, 
            Uri url, 
            BitmapFactory.Options options) 
       throws FileNotFoundException, IOException { 
    InputStream input = cr.openInputStream(url); 
    Bitmap bitmap = BitmapFactory.decodeStream(input, null, options); 
    input.close(); 
    return bitmap; 
} 

Verbrauch:

final BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize = 8; 

Bitmap bm = getBitmap(getActivity().getContentResolver(), 
         Uri.parse(selectedImageToUri), 
         options); 
+0

danke Weston, für die Bearbeitung und für deine Antwort, also gebe ich dir einen Reputationspunkt, aber ich akzeptiere als Antwort Attaulah, das war mir zuerst und weiter auch ein netter schneller Gewinn, der dem Manifest einen großen Heap hinzufügt, der auch eine interessante Alternative ist (obwohl natürlich nicht optim al) – trocchietto

+1

Das liegt an dir, aber für den Rekord war meine Antwort zuerst. Die Reihenfolge der Antworten ist nicht chronologisch. – weston

+0

Es tut mir leid von ganzem Herzen Ich kannte Weston nicht. Es wäre eine Utopie, deine Freundlichkeit zu tauschen und einen Posten zu suchen, wo du um Hilfe bittest, denn mein Wissensstand ist im Vergleich zu dir definitiv ein fernes Licht. Ich bin sogar noch kein Android-Entwickler, der seinen Lebensunterhalt verdient. Mein aufrichtiges Kompliment für den goldenen Kopf deines Avatars ist einfach unglaublich imo. Hoffe wirklich, in Zukunft für dich wertvoll zu sein. Wieder tut mir leid Weston – trocchietto

1

Ich habe viel Zeit mit diesem Problem verbracht, aber niemand wird mir eine genaue Antwort geben und schließlich habe ich es gelöst. Zuerst erstellen Sie Methode und bieten Image URI als Argument, und dies wird Bitmap im Grunde hier ich berechnet Bildgröße auf der Grundlage von, können wir Speicher sowie Bild verwalten und erhalten genaues Bild in Bitmap-Form.

können Sie sogar anzeigen 5000 × 8000 und 12MiB Bild ohne Fehlercode getestet wird nur kopieren in Ihrer Klasse kopieren und genießen.

Verwenden

Bitmap mBitmap = getPhoto(MYIMAGEURI); 

URI Methode Geben und erhalten Bitmap

Bitmap getPhoto(Uri selectedImage) { 
    DisplayMetrics metrics = new DisplayMetrics(); 
    getWindowManager().getDefaultDisplay().getMetrics(metrics); 
    int height = metrics.heightPixels; 
    int width = metrics.widthPixels; 
    Bitmap photoBitmap = null; 
    InputStream inputStream = null; 
    try { 
     inputStream = getContentResolver().openInputStream(selectedImage); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 
    BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); 
    bitmapOptions.inJustDecodeBounds = true; 
    BitmapFactory.decodeStream(inputStream, null, bitmapOptions); 
    int imageWidth = bitmapOptions.outWidth; 
    int imageHeight = bitmapOptions.outHeight; 

    @SuppressWarnings("unused") 
    InputStream is = null; 
    try { 
     is = getContentResolver().openInputStream(selectedImage); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 
    float scale = 1.0f; 

    if (imageWidth < imageHeight) { 
     if (imageHeight > width * 1.0f) { 
      scale = width * 1.0f/(imageHeight * 1.0f); 
     } 

    } else { 
     if (imageWidth > width * 1.0f) { 
      scale = width * 1.0f/(imageWidth * 1.0f); 
     } 

    } 

    photoBitmap = decodeSampledBitmapFromResource(this, 
      selectedImage, (int) (imageWidth * scale), 
      (int) (imageHeight * scale)); 
    return photoBitmap; 
} 

Decode Bitmap Probe mit Bildgröße

public static Bitmap decodeSampledBitmapFromResource(Context context, 
      Uri uri, int reqWidth, int reqHeight) { 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    InputStream is = null; 
    try { 
     is = context.getContentResolver().openInputStream(uri); 
    } catch (FileNotFoundException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
    BitmapFactory.decodeStream(is, null, options); 

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

    // Decode editBitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    InputStream inputs = null; 
    try { 
     inputs = context.getContentResolver().openInputStream(uri); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 

    return BitmapFactory.decodeStream(inputs, null, options); 
} 

berechnen Probengröße

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) { 

     // Calculate ratios of height and width to requested height and 
     // width 
     final int heightRatio = Math.round((float) height 
       /(float) reqHeight); 
     final int widthRatio = Math.round((float) width/(float) reqWidth); 

     // Choose the smallest ratio as inSampleSize value, this will 
     // guarantee 
     // a final image with both dimensions larger than or equal to the 
     // requested height and width. 
     inSampleSize = Math.min(heightRatio, widthRatio); 
     // inSampleSize = heightRatio < widthRatio ? heightRatio : 
     // widthRatio; 
    } 

    return inSampleSize; 
} 

oder möglich sein kann, zu manifiest.xml in einer Zeile Code unter Verwendung gelöst ist in Anwendung Tag Verwendung dieses

android:largeHeap="true" 
+0

Vergessen Sie nicht, diese Streams zu schließen. Siehe meine Antwort. – weston

+0

Bitte editiere meine Antwort wo Stream benötigt wird. – Attaullah

+0

Nein, deine Antwort hat zu viele andere Probleme, wenn ich nur den Teil davon bearbeite, würde ich die Schuld an den anderen Problemen teilen, und ich habe keine Zeit für eine vollständige Neufassung. – weston