1. Nimm jetzt an unserem 2. ADVENT-Gewinnspiel teil - Alle Informationen findest Du hier!

OutofMemory BitmapSize exceeds wieder mal !

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von BFK, 12.07.2012.

  1. BFK, 12.07.2012 #1
    BFK

    BFK Threadstarter Erfahrener Benutzer

    Beiträge:
    160
    Erhaltene Danke:
    10
    Registriert seit:
    08.12.2010
    Hallo,
    Ich habe folgendes Problem. Ich versuche aus einem View eine Image zu erstellen. Zuerst habe ich durch (v ist mein View)
    Code:
    Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
    
    versucht ein Bitmap draus zu machen. Hat auch gut funktioniert, bis ich eine etwas grössere Bitmap erstellen müsste, da bekam ich eine NullPointerException. Später erfuhr ich im inet, dass es ein Grenze beim Cache gibt und somit dies der falsche Weg wäre, wenn man grössere Bitmaps bräuchte (deshalb die Exception).

    Dann fand ich folgende Methode:

    Code:
    public static Bitmap loadBitmapFromView(View v) {
            Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);                
            Canvas c = new Canvas(b);
            v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
            v.draw(c);
            return b;
        }
    
    Diese funktioniert auch gut mit kleine Bitmaps, doch bei grösseren bekomme ich eine OutOfmemory-Exception und zwar bei der Zeile:
    Code:
    Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);
    
    Wie kann ich das umgehen..?

    Als ich Bitmaps über Resourcen oder einem Pfad laden wollte, bekam ich auch genau diese Exception,aber da hat folgendes Tutorial sehr geholfen..:
    Loading Large Bitmaps Efficiently | Android Developers
    ...doch hier ist es ein wenig anders. Habe hier leider keine resource oder File, sondern ein View.

    Was kann ich tun..?
     
  2. Thyrion, 13.07.2012 #2
    Thyrion

    Thyrion Ehrenmitglied

    Beiträge:
    11,845
    Erhaltene Danke:
    2,450
    Registriert seit:
    21.07.2009
    Phone:
    Nexus 5X
    Nur mal aus Neugier, von welcher Größe reden wir hier? Also wie hoch und breit würde das Bitmap denn sein?
     
  3. Tom299, 13.07.2012 #3
    Tom299

    Tom299 Android-Experte

    Beiträge:
    602
    Erhaltene Danke:
    120
    Registriert seit:
    31.08.2011
    bei stackoverflow hab ich was ähnliches gefunden:
    Code:
    Bitmap b = Bitmap.createBitmap(theView.getWidth(), theView.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);
    theView.draw(c);
    
    wieso benutzt du view.getLayoutParams().width anstatt direkt view.getWidth?
     
  4. StefMa, 13.07.2012 #4
    StefMa

    StefMa Gewerbliches Mitglied

    Beiträge:
    2,054
    Erhaltene Danke:
    413
    Registriert seit:
    16.10.2010
    Zuletzt bearbeitet: 13.07.2012
  5. BFK, 13.07.2012 #5
    BFK

    BFK Threadstarter Erfahrener Benutzer

    Beiträge:
    160
    Erhaltene Danke:
    10
    Registriert seit:
    08.12.2010
    Hallo und danke euch für eure Antworten..!

    @Thyrion
    Beim nächsten compilen werde ich mir mal die Grösse abrufen. Aber wozu ist das wichtig..? Einfach nur aus Neugierde..?

    @Tom299
    Ich benutzte doch "view.getLayoutParams.width/height" oder meisnt du was anderes..?

    @IceClaw
    Habe natürlich schon Google befragt. Und wie bereits gesagt hatte dieses Problem früher bei Images, die Ich von eine File geladen habe. Da hilft genau das was bei stackoverflow steht. Obwohl ich muss schon sagen, dass bei dem Code-abschnitt von stackoverflow immer noch ein OutOfMemory-Error passieren kann (selbst vor ein paar Monaten getestet, habe mich auch gewundert wieso es 263+ gab). Der bessere Code (zumind. bis jetzt noch nie Probleme gehabt) ist der den ich am ersten Beitrag verlinkt habe, also der Loading Large Bitmaps Efficiently | Android Developers . Egal zurück zum Thema: In meinem Fall habe ich kein Image oder Bitmap irgendwo gespeichert, sondern ich will es ja von einem View sozusagen "fotografieren". Und genau da bekomme ich meinem Fehler. Wie kann ich hier vorgehen..?
     
  6. Thyrion, 13.07.2012 #6
    Thyrion

    Thyrion Ehrenmitglied

    Beiträge:
    11,845
    Erhaltene Danke:
    2,450
    Registriert seit:
    21.07.2009
    Phone:
    Nexus 5X
    Naja, eigentlich wegen dem Bitmap.Config.ARGB_8888 (= 4 Bytes pro Pixel). Da kann bei entsprechender Größe einiges zusammenkommen und dementsprechend auch schnell der Speicher voll sein.

    Beispiel: Ein Bild 480x800 (Auflösung bei meinem Desire) würde so ~1.5 MB belegen.
     
  7. BFK, 13.07.2012 #7
    BFK

    BFK Threadstarter Erfahrener Benutzer

    Beiträge:
    160
    Erhaltene Danke:
    10
    Registriert seit:
    08.12.2010
    Das Bitmap hat eine Auflösung von 2758 x 2758.
    Du fragst dich jetzt bestimmt, wieso so gross, wenn eh bei den meisten geräten (wenn nicht alle) nur ein Teil angezeigt erden kann..?

    Das Bild befindet sich auf einer Karte (leider NICHT Google Maps), also zeigt sozusagen eine Bereich auf einer Karte an. Wenn der Nutzer diese Karte verschiebt sieht er die zuvor nicht sichtbare Bereiche des Bidles.

    Die Frage ist, was kann ich jetzt hier tun. Wie kann ich die Grösse reduzieren..?
     
  8. 1zu0, 13.07.2012 #8
    1zu0

    1zu0 Junior Mitglied

    Beiträge:
    28
    Erhaltene Danke:
    2
    Registriert seit:
    16.12.2010
    Phone:
    HTC Desire
    wie wäre es das Bild zu zerschneiden und nur den jeweils nötigen Teil zu laden.
    Also zb aus einem Bild 9 Teile. 3x3. Nur als Beispiel.

    Wie das gehen soll, weiss ich allerdings nicht ;)
     
  9. BFK, 13.07.2012 #9
    BFK

    BFK Threadstarter Erfahrener Benutzer

    Beiträge:
    160
    Erhaltene Danke:
    10
    Registriert seit:
    08.12.2010
    Hi 1zu0,
    Deine Idee ist nicht schlecht, doch leider sehr sehr aufwending.
    Weil ich muss dann jedes Mal wenn der User die Map bewegt alles wieder neu berechnen und neu laden.

    Es muss doch unkomplizierter gehen..!

    Zum Beispiel könnte ich denn nicht eine andere Klasse als Bitmap benutzen.?

    Oder könnte ich eine ähniliche "createBitmap-Methode" benutzen, die das Bild komprimiert..?

    Oder k.A. irgendwas, das ohne soooviel Aufwand gehen würde..!
     
  10. Thyrion, 13.07.2012 #10
    Thyrion

    Thyrion Ehrenmitglied

    Beiträge:
    11,845
    Erhaltene Danke:
    2,450
    Registriert seit:
    21.07.2009
    Phone:
    Nexus 5X
    Dir ist klar, dass das Bild allein knapp 30 MB belegen würde? Da kann ich mir die OutOfMemoryException (gerade bei mobilen Geräten, die nicht gigabyteweise RAM zur Verfügung haben) gut vorstellen.
     
  11. 1zu0, 13.07.2012 #11
    1zu0

    1zu0 Junior Mitglied

    Beiträge:
    28
    Erhaltene Danke:
    2
    Registriert seit:
    16.12.2010
    Phone:
    HTC Desire
    @Thyrion: Du beziehst Dich auf mich?, nehm ich jetzt mal an.
    Ehrlich gesagt hätt ich jetzt gemutmaßt, dass es aufs selbe rauskommt, aber gut möglich, dass dem nicht so ist :) Wenns geht, bitte ich um Aufklärung.
     
  12. Thyrion, 13.07.2012 #12
    Thyrion

    Thyrion Ehrenmitglied

    Beiträge:
    11,845
    Erhaltene Danke:
    2,450
    Registriert seit:
    21.07.2009
    Phone:
    Nexus 5X
    Nein, ich beziehe mich "Das Bitmap hat eine Auflösung von 2758 x 2758." vom TE und seine Verwunderung über die Speicherknappheit :)

    Nochwas zu der Exception: Die 30 MB freier Speicher müssen übrigens am Stück frei sein - also als ein großer Block sozusagen. Und einfach mal so den Speicher umschichten, ist teuer (im Sinne von Belastung für Speicher, CPU und damit Akku). Also selbst wenn Du rechnerisch feststellst, dass genug Speicher frei ist, wirst du diese Exception bekommen, wenn das ganze nicht am Stück ist.
     
  13. BFK

    BFK Threadstarter Erfahrener Benutzer

    Beiträge:
    160
    Erhaltene Danke:
    10
    Registriert seit:
    08.12.2010
    Klar belegt das Bitmap viel Speicher, aber mir fällt nichts ein, womit ich das verhindern kann..!
     
  14. StefMa, 14.07.2012 #14
    StefMa

    StefMa Gewerbliches Mitglied

    Beiträge:
    2,054
    Erhaltene Danke:
    413
    Registriert seit:
    16.10.2010
    Mach den Bereich kleiner!

    Gesendet von meinem Galaxy Nexus mit der Android-Hilfe.de App
     
  15. BFK

    BFK Threadstarter Erfahrener Benutzer

    Beiträge:
    160
    Erhaltene Danke:
    10
    Registriert seit:
    08.12.2010
    Also du schlägst mir im Endeffekt was ähnlisches vor, was 1zu0 gesagt hat oder nicht..?
    Wie es aussieht ist das vielleicht die einzige Lösung..!
     
  16. StefMa, 15.07.2012 #16
    StefMa

    StefMa Gewerbliches Mitglied

    Beiträge:
    2,054
    Erhaltene Danke:
    413
    Registriert seit:
    16.10.2010
    Nein. Du sagst, dass deine User einen Bereich auf einer Karte sehen bzw auswählen können. Diesen Bereich einfach kleiner machen..

    Gesendet von meinem Galaxy Nexus mit der Android-Hilfe.de App
     
  17. BFK

    BFK Threadstarter Erfahrener Benutzer

    Beiträge:
    160
    Erhaltene Danke:
    10
    Registriert seit:
    08.12.2010
    Nein ich meinte, dass es auf der Karte einen Bereich gibt, der was anzeigt, sagen wir mal mein Bitmap besteht aus einem durchsichtigen Rechteck.
    Wenn der User in die Karte reinzommt, wird dieses Rechteck logischerweise grösser und je näher er reinzoomt desto grösser wird dieses Rechteck und somit auch mein Bitmap. Genau dann habe ich die OutOfMemory-Exception.

    Somit kann ich diesen Bereich (im Beispiel das Rechteck) nicht kleiner machen, denn dann wird der falsche Bereich bedeckt.
     
  18. Thyrion, 16.07.2012 #18
    Thyrion

    Thyrion Ehrenmitglied

    Beiträge:
    11,845
    Erhaltene Danke:
    2,450
    Registriert seit:
    21.07.2009
    Phone:
    Nexus 5X
    Wieso? Du musst es doch nur richtig (relativ zum Kartenausschnitt) positionieren (und das darzustellende natürlich entsprechend anpassen).
     
  19. BFK

    BFK Threadstarter Erfahrener Benutzer

    Beiträge:
    160
    Erhaltene Danke:
    10
    Registriert seit:
    08.12.2010
    Das ist dann wiederum die Lösung die 1zu0 vorgeschlagen hab. Die geht natürlich, ist aber wie schon vorher gesagt aufwendig..!
     

Diese Seite empfehlen