OutofMemory BitmapSize exceeds wieder mal !

B

BFK

Fortgeschrittenes Mitglied
11
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..?
 
Nur mal aus Neugier, von welcher Größe reden wir hier? Also wie hoch und breit würde das Bitmap denn sein?
 
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?
 
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..?
 
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.
 
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..?
 
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 ;)
 
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..!
 
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.
 
@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.
 
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.
 
Klar belegt das Bitmap viel Speicher, aber mir fällt nichts ein, womit ich das verhindern kann..!
 
BFK schrieb:
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..?

Mach den Bereich kleiner!

Gesendet von meinem Galaxy Nexus mit der Android-Hilfe.de App
 
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..!
 
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
 
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.
 
BFK schrieb:
Somit kann ich diesen Bereich (im Beispiel das Rechteck) nicht kleiner machen, denn dann wird der falsche Bereich bedeckt.
Wieso? Du musst es doch nur richtig (relativ zum Kartenausschnitt) positionieren (und das darzustellende natürlich entsprechend anpassen).
 
Thyrion schrieb:
Wieso? Du musst es doch nur richtig (relativ zum Kartenausschnitt) positionieren (und das darzustellende natürlich entsprechend anpassen).

Das ist dann wiederum die Lösung die 1zu0 vorgeschlagen hab. Die geht natürlich, ist aber wie schon vorher gesagt aufwendig..!
 

Ähnliche Themen

W
  • WuDiDong
Antworten
3
Aufrufe
764
jogimuc
J
K
Antworten
10
Aufrufe
1.507
swa00
swa00
H
Antworten
3
Aufrufe
886
markus.tullius
markus.tullius
Zurück
Oben Unten