BitmapFactory.decodeStream out-of-memory-trotz des reduzierten stichprobenumfangs
Ich habe gelesen, dass viele related posts bezüglich Speicherzuordnung Probleme mit der Decodierung von bitmaps, aber bin immer noch nicht finden die Lösung für das folgende problem auch nach der Verwendung der zur Verfügung gestellte code in der offiziellen website.
Hier ist mein code:
public static Bitmap decodeSampledBitmapFromResource(InputStream inputStream, int reqWidth, int reqHeight) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
try {
while ((len = inputStream.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
InputStream is1 = new ByteArrayInputStream(baos.toByteArray());
InputStream is2 = new ByteArrayInputStream(baos.toByteArray());
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is1, null, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inPurgeable = true;
options.inInputShareable = true;
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
return BitmapFactory.decodeStream(is2, null, options);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
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 = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
bitmap = decodeSampledBitmapFromResource(inputStream, 600, 600);
Bin ich immer "Out of memory" - Fehlermeldung auf einem 3250016 - byte-Zuordnung" in dieser Zeile:
return BitmapFactory.decodeStream(is2, null, options);
Es scheint mir, dass 3,2 MB ist klein genug, um zugeordnet werden. Wohin gehe ich falsch? Wie kann ich dieses Problem lösen?
BEARBEITEN
Nach einem Blick in diese Lösung HIER von N-Joy, es funktioniert gut mit der Benötigten Größe 300, aber meine gewünschte Größe ist 800, so bin ich noch immer der Fehler.
InformationsquelleAutor der Frage Goofy | 2013-03-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die Methode
decodeSampledBitmapFromResource
ist Erinnerung nicht effizient, denn es werden 3 streams: die ByteArrayOutputStream baos, ByteArrayInputStream is1 und ByteArrayInputStream is2, jedem der Läden die gleiche stream-Daten des Bildes (ein byte array für jedes).Und wenn ich den test mit meinem Gerät (LG nexus 4) zum Dekodieren von 2560x1600 image auf SDcard Zielgröße 800 dauert es, so etwas wie dieses:
Können wir sehen: zu viel Speicher alloziert (28.5 MB) einfach zu entschlüsseln 4096000 ein pixel-Bild.
Lösung: wir Lesen den InputStream und speichern Sie die Daten direkt in ein byte-array und verwenden Sie diese byte-array für den rest der Arbeit.
Beispiel-code:
Die Methode, die die Berechnung:
Und das Ergebnis:
InformationsquelleAutor der Antwort Binh Tran
Dies ist ein häufiges Problem, das Benutzer normalerweise Gesichter beim spielen mit großen bitmaps, und es gibt viele Fragen diskutierte auf der Website, hierhierhier und hier und viele mehr, auch wenn der Benutzer nicht in der Lage zu manipulieren die exakte Lösung.
Stolperte ich über eine Bibliothek irgendwann zurück, das die Verwaltung der bitmaps reibungslos und andere links, die ich unten aufgelistet. Hoffe, das hilft!
smoothie-Bibliothek
Android-BitmapCache
Android-Universal-Image-Loader
Lösung für OutOfMemoryError: bitmap size exceeds VM budget
InformationsquelleAutor der Antwort RobinHood
ARGB_8888
verwendet mehr Speicher als es dauert, Alpha-color-Wert, so mein Vorschlag ist, verwenden SieRGB_565
wie gesagt HIERHinweis: die Qualität wird etwas geringer im Vergleich zu
ARGB_8888
.InformationsquelleAutor der Antwort nidhi_adiga
Sind Sie wahrscheinlich das festhalten an bisherigen bitmap-Referenzen. Ich vermute, dass Sie die Ausführung dieser code mehrere Male und nie ausführen
bitmap.recycle()
. Speicher wird zwangsläufig ausgehen.InformationsquelleAutor der Antwort Paul Lammertsma
Hatte ich viele Probleme mit Bitmap-Speicher-Nutzung.
Ergebnisse:
InformationsquelleAutor der Antwort AVEbrahimi
Verwenden WebView dynamisch geladen, so viele Bilder wie Sie möchten, es ist gebaut mit NDK (niedrige Stufe), so hat keine GDI-heap-Speicher Einschränkungen.
Es funktioniert glatt und schnell 🙂
InformationsquelleAutor der Antwort AVEbrahimi
Out-of-memory-Probleme beim Dekodieren von bitmaps werden nicht oft verknüpft mit dem Bild, die Größe, die Sie decodieren.
Natürlich, wenn Sie versuchen, öffnen Sie ein Bild 5000x5000px Sie werden nicht mit einem OutOfMemoryError, aber mit der Größe von 800x800px es ist vollkommen vernünftig und sollte funktionieren.
Wenn Ihr Gerät aus dem Speicher mit 3.2 MB Bild es ist wahrscheinlich, weil Sie undicht Kontext irgendwo in der app.
Es ist der erste Teil der dieser Beitrag:
Was es bedeutet, dass Sie mit Aktivität, Kontext-Komponenten, sollten nicht verhindern, dass Sie von der garbage Collection freigegeben. Da Komponenten oft von Aktivitäten, diese Aktivitäten sind nicht die GC und Ihre java-heap wird sehr schnell wachsen und Ihre app Absturz zur einen oder anderen Zeit.
Als Raghunandan, sagte, müssen Sie eine MATTE zu finden, welche Aktivität/Komponente gehalten wird, und entfernen Sie die Rahmen undicht.
Der beste Weg, fand ich jetzt zu erkennen, Kontext-Leck ist die Orientierung ändern.
Zum Beispiel, drehen Sie Ihre ActivityMain mehrmals, führen MATTE und prüfen Sie, ob Sie nur eine Instanz von ActivityMain. Wenn Sie mehrere Einsen (so viel wie Drehung verpasst) es bedeutet, dass es einen Zusammenhang Leck.
Fand ich vor Jahren eine gutes tutorial über die Verwendung von MAT. Vielleicht ist es besser jetzt.
Andere Beiträge von memory leaks:
Android - Speicherverlust oder?
Out-of-memory-Fehler auf android-emulator, aber nicht auf dem Gerät
InformationsquelleAutor der Antwort ol_v_er
Haben Sie einen Blick auf dieses video. http://www.youtube.com/watch?v=_CruQY55HOk. Verwenden Sie nicht system.gc() wie vorgeschlagen im video. Verwenden Sie eine MATTE Analyzer heraus zu finden, memory leaks. Der zurückgegebene bitmap ist zu groß, verursacht Speicherverlust, denke ich.
InformationsquelleAutor der Antwort Raghunandan
Es scheint, Sie haben große Bild angezeigt wird.
Können Sie Bild herunterladen und speichern, um sdcard ( Beispiel ), dann können Sie Benutzer diese
code um Bild von sdcard.
InformationsquelleAutor der Antwort MAC
ich hatte auch gleiche problem früher.. und ich habe es geschafft es durch die Verwendung dieser Funktion, wo man die Skala als Ihre erforderliche Breite und Höhe.
beziehen und die Memory-Leak-Fehler Android und Fehler beim laden der Bilder zu gridview android
InformationsquelleAutor der Antwort Sanket Kachhela