1389 Stimmen

Seltsames OutOfMemory-Problem beim Laden eines Bildes in ein Bitmap-Objekt

Ich habe eine ListView mit ein paar Bildschaltflächen in jeder Zeile. Wenn der Benutzer auf die Listenzeile klickt, wird eine neue Aktivität gestartet. Aufgrund eines Problems mit dem Kamera-Layout musste ich meine eigenen Registerkarten erstellen. Die Aktivität, die für das Ergebnis gestartet wird, ist eine Karte. Wenn ich auf meine Schaltfläche klicke, um die Bildvorschau zu starten (Laden eines Bildes von der SD-Karte), kehrt die Anwendung von der Aktivität zurück zur ListView Aktivität zum Ergebnis-Handler, um meine neue Aktivität, die nichts anderes als ein Bild-Widget ist, neu zu starten.

Die Bildvorschau auf der Seite ListView wird mit dem Cursor durchgeführt und ListAdapter . Dies macht es ziemlich einfach, aber ich bin mir nicht sicher, wie ich ein verkleinertes Bild (d.h. kleinere Bitgröße nicht Pixel als die src für die Bild-Schaltfläche im laufenden Betrieb. Also habe ich einfach die Größe des Bildes, das von der Handykamera kam, geändert.

Das Problem ist, dass ich eine OutOfMemoryError wenn er versucht, zurückzugehen und die 2. Aktivität erneut zu starten.

  • Gibt es eine Möglichkeit, den Listenadapter einfach zeilenweise zu erstellen, wobei ich die Größe während des Betriebs ändern kann ( bitweise )?

Dies wäre wünschenswert, da ich auch einige Änderungen an den Eigenschaften der Widgets/Elemente in jeder Zeile vornehmen muss, da ich aufgrund des Fokusproblems nicht in der Lage bin, eine Zeile mit dem Touchscreen auszuwählen. ( Ich kann Rollerball verwenden. )

  • Ich weiß, dass ich die Größe außerhalb des Bandes ändern und mein Bild speichern kann, aber das ist nicht wirklich das, was ich tun möchte, aber ein Beispielcode dafür wäre schön.

Sobald ich das Bild auf dem Bildschirm deaktiviert habe ListView hat es wieder gut funktioniert.

Zu Ihrer Information: So habe ich es gemacht:

String[] from = new String[] { DBHelper.KEY_BUSINESSNAME, DBHelper.KEY_ADDRESS,
    DBHelper.KEY_CITY, DBHelper.KEY_GPSLONG, DBHelper.KEY_GPSLAT,
    DBHelper.KEY_IMAGEFILENAME  + ""};
int[] to = new int[] { R.id.businessname, R.id.address, R.id.city, R.id.gpslong,
    R.id.gpslat, R.id.imagefilename };
notes = new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to);
setListAdapter(notes);

どこ R.id.imagefilename es un ButtonImage .

Hier ist mein LogCat:

01-25 05:05:49.877: ERROR/dalvikvm-heap(3896): 6291456-byte external allocation too large for this process.
01-25 05:05:49.877: ERROR/(3896): VM wont let us allocate 6291456 bytes
01-25 05:05:49.877: ERROR/AndroidRuntime(3896): Uncaught handler: thread main exiting due to uncaught exception
01-25 05:05:49.917: ERROR/AndroidRuntime(3896): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:304)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:149)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:174)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.graphics.drawable.Drawable.createFromPath(Drawable.java:729)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.ImageView.resolveUri(ImageView.java:484)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.ImageView.setImageURI(ImageView.java:281)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.SimpleCursorAdapter.setViewImage(SimpleCursorAdapter.java:183)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:129)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.CursorAdapter.getView(CursorAdapter.java:150)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.AbsListView.obtainView(AbsListView.java:1057)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.ListView.makeAndAddView(ListView.java:1616)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.ListView.fillSpecific(ListView.java:1177)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.ListView.layoutChildren(ListView.java:1454)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.AbsListView.onLayout(AbsListView.java:937)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.View.layout(View.java:5611)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1108)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.onLayout(LinearLayout.java:922)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.View.layout(View.java:5611)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.FrameLayout.onLayout(FrameLayout.java:294)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.View.layout(View.java:5611)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:999)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.LinearLayout.onLayout(LinearLayout.java:920)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.View.layout(View.java:5611)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.widget.FrameLayout.onLayout(FrameLayout.java:294)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.View.layout(View.java:5611)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.ViewRoot.performTraversals(ViewRoot.java:771)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1103)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.os.Handler.dispatchMessage(Handler.java:88)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.os.Looper.loop(Looper.java:123)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at android.app.ActivityThread.main(ActivityThread.java:3742)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at java.lang.reflect.Method.invokeNative(Native Method)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at java.lang.reflect.Method.invoke(Method.java:515)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)
01-25 05:05:49.917: ERROR/AndroidRuntime(3896):     at dalvik.system.NativeStart.main(Native Method)
01-25 05:10:01.127: ERROR/AndroidRuntime(3943): ERROR: thread attach failed 

Ich habe auch einen neuen Fehler beim Anzeigen eines Bildes:

22:13:18.594: DEBUG/skia(4204): xxxxxxxxxxx jpeg error 20 Improper call to JPEG library in state %d
22:13:18.604: INFO/System.out(4204): resolveUri failed on bad bitmap uri: 
22:13:18.694: ERROR/dalvikvm-heap(4204): 6291456-byte external allocation too large for this process.
22:13:18.694: ERROR/(4204): VM won't let us allocate 6291456 bytes
22:13:18.694: DEBUG/skia(4204): xxxxxxxxxxxxxxxxxxxx allocPixelRef failed

9 Stimmen

Ich löste dies, indem ich Bitmap.decodeStream oder decodeFile vermied und die Methode BitmapFactory.decodeFileDescriptor verwendete.

2 Stimmen

Ich auch konfrontiert ähnliches Problem paar Wochen zurück und ich löste es durch Skalierung Bilder bis zu optimalen Punkt. Ich habe komplette Ansatz in meinem Blog geschrieben codingjunkiesforum.wordpress.com/2014/06/12/ und lud ein komplettes Beispielprojekt mit OOM-anfälligem Code im Vergleich zu OOM-Proof-Code aufhttps://github.com/shailendra123/BitmapHandlingDemo hoch.

2 Stimmen

Vollständige Lösung .. stackoverflow.com/a/24135283/294884

922voto

Fedor Punkte 43061

Um den OutOfMemory-Fehler zu beheben, sollten Sie etwa so vorgehen:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap = BitmapFactory.decodeStream(is, null, options);

Este inSampleSize Option reduziert den Speicherverbrauch.

Hier ist eine vollständige Methode. Zunächst wird die Bildgröße ermittelt, ohne den Inhalt selbst zu dekodieren. Dann findet sie die beste inSampleSize Wert sollte eine Potenz von 2 sein, und schließlich wird das Bild dekodiert.

// Decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f) {
    try {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f), null, o);

        // The new size we want to scale to
        final int REQUIRED_SIZE=70;

        // Find the correct scale value. It should be the power of 2.
        int scale = 1;
        while(o.outWidth / scale / 2 >= REQUIRED_SIZE && 
              o.outHeight / scale / 2 >= REQUIRED_SIZE) {
            scale *= 2;
        }

        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}

32 Stimmen

Beachten Sie, dass 10 möglicherweise nicht der beste Wert für inSampleSize ist. Die Dokumentation schlägt vor, Potenzen von 2 zu verwenden.

71 Stimmen

Ich stehe vor demselben Problem wie Chrispix, aber ich glaube nicht, dass die Lösung hier das Problem wirklich löst, sondern es eher umgeht. Das Ändern der Samplegröße reduziert den Speicherverbrauch (auf Kosten der Bildqualität, was für eine Bildvorschau wahrscheinlich in Ordnung ist), aber es wird die Ausnahme nicht verhindern, wenn ein ausreichend großer Bildstrom dekodiert wird, oder wenn mehrere Bildströme dekodiert werden. Wenn ich eine bessere Lösung finde (und vielleicht gibt es keine), werde ich hier eine Antwort posten.

5 Stimmen

Sie brauchen nur eine geeignete Größe, die der Pixeldichte des Bildschirms entspricht, zum Zoomen usw. können Sie eine Probe des Bildes mit einer höheren Dichte nehmen.

693voto

AdamK Punkte 20668

El Android-Schulung Klasse, " Effiziente Anzeige von Bitmaps ", bietet einige gute Informationen zum Verständnis und zum Umgang mit der Ausnahme "java.lang.OutOfMemoryError: bitmap size exceeds VM budget when loading Bitmaps".


Bitmap-Abmessungen und -Typ lesen

El BitmapFactory Klasse bietet mehrere Dekodierungsmethoden ( decodeByteArray() , decodeFile() , decodeResource() usw.) zur Erstellung eines Bitmap aus verschiedenen Quellen. Wählen Sie die für Ihre Bilddatenquelle am besten geeignete Dekodiermethode. Diese Methoden versuchen, Speicher für die konstruierte Bitmap zuzuweisen und können daher leicht zu einem OutOfMemory Ausnahme. Jede Art von Dekodiermethode hat zusätzliche Signaturen, mit denen Sie die Dekodieroptionen über die Option BitmapFactory.Options Klasse. Die Einstellung der inJustDecodeBounds Eigenschaft zu true während die Dekodierung die Speicherzuweisung vermeidet und null für das Bitmap-Objekt, aber die Einstellung outWidth , outHeight y outMimeType . Mit dieser Technik können Sie die Abmessungen und den Typ der Bilddaten vor dem Aufbau (und der Speicherzuweisung) der Bitmap lesen.

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

Zur Vermeidung von java.lang.OutOfMemory Ausnahmen: Überprüfen Sie die Abmessungen einer Bitmap, bevor Sie sie dekodieren, es sei denn, Sie vertrauen absolut darauf, dass die Quelle Ihnen Bilddaten in vorhersehbarer Größe liefert, die bequem in den verfügbaren Speicher passen.


Laden einer verkleinerten Version in den Speicher

Da die Bildabmessungen nun bekannt sind, können sie verwendet werden, um zu entscheiden, ob das vollständige Bild in den Speicher geladen werden soll oder ob stattdessen eine unterabgetastete Version geladen werden soll. Hier sind einige Faktoren zu berücksichtigen:

  • Geschätzter Speicherverbrauch für das Laden des vollständigen Bildes im Speicher.
  • Die Menge an Speicher, die Sie bereit sind, für das Laden dieses Bildes zu verwenden, unter Berücksichtigung aller anderen Speicheranforderungen Ihrer Anwendung.
  • Abmessungen der Ziel-ImageView oder UI-Komponente, in die das Bild geladen werden soll.
  • Bildschirmgröße und -dichte des aktuellen Geräts.

Es lohnt sich zum Beispiel nicht, ein Bild mit 1024x768 Pixeln in den Speicher zu laden, wenn es später in einem 128x96 Pixel großen Thumbnail in einer Website angezeigt wird. ImageView .

Um den Decoder anzuweisen, das Bild zu unterteilen und eine kleinere Version in den Speicher zu laden, setzen Sie inSampleSize a true in Ihrem BitmapFactory.Options Objekt. Beispielsweise kann ein Bild mit einer Auflösung von 2048x1536, das mit einer inSampleSize von 4 ergibt eine Bitmap von etwa 512x384. Das Laden dieses Bildes in den Speicher benötigt 0,75 MB statt 12 MB für das gesamte Bild (unter der Annahme einer Bitmap-Konfiguration von ARGB_8888 ). Hier ist eine Methode zur Berechnung eines Stichprobenumfangs, der eine Potenz von zwei ist, basierend auf einer Zielbreite und -höhe:

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;
}

Hinweis : Es wird eine Zweierpotenz berechnet, da der Decoder einen Endwert durch Abrunden auf die nächstliegende Zweierpotenz, wie in der inSampleSize Dokumentation.

Um diese Methode zu verwenden, dekodieren Sie zunächst mit inJustDecodeBounds eingestellt auf true, pass the options through and then decode again using the new inSampleSize value and inJustDecodeBounds set to false":

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
    int reqWidth, int reqHeight) {

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

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

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

Diese Methode macht es einfach, eine Bitmap von beliebiger Größe in eine ImageView die ein 100x100 Pixel großes Miniaturbild anzeigt, wie im folgenden Beispielcode gezeigt:

mImageView.setImageBitmap(
    decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

Sie können ein ähnliches Verfahren anwenden, um Bitmaps aus anderen Quellen zu dekodieren, indem Sie die entsprechenden BitmapFactory.decode* Methode nach Bedarf.

24 Stimmen

Diese Antwort wird diskutiert auf meta

10 Stimmen

Diese Antwort (abgesehen von den Informationen, die über den Link erreicht werden) bietet nicht viel von einer Lösung, was eine Antwort angeht. Die wichtigen Teile des Links sollten in die Frage eingefügt werden.

8 Stimmen

Diese Antwort, wie auch die Frage und die anderen Antworten, ist ein Community-Wiki, also etwas, das die Community durch Bearbeitung beheben kann, etwas, das kein Eingreifen eines Moderators erfordert.

383voto

Thomas Vervest Punkte 2131

Ich habe eine kleine Verbesserung am Code von Fedor vorgenommen. Er tut im Grunde das Gleiche, aber ohne die (meiner Meinung nach) hässliche while-Schleife, und er ergibt immer eine Zweierpotenz. Ein großes Lob an Fedor für die ursprüngliche Lösung. Ich kam nicht weiter, bis ich seine Lösung fand, und dann konnte ich diese Lösung erstellen :)

 private Bitmap decodeFile(File f){
    Bitmap b = null;

        //Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;

    FileInputStream fis = new FileInputStream(f);
    BitmapFactory.decodeStream(fis, null, o);
    fis.close();

    int scale = 1;
    if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
        scale = (int)Math.pow(2, (int) Math.ceil(Math.log(IMAGE_MAX_SIZE / 
           (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
    }

    //Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    fis = new FileInputStream(f);
    b = BitmapFactory.decodeStream(fis, null, o2);
    fis.close();

    return b;
}

42 Stimmen

Ja, du hast Recht, obwohl es nicht so schön ist. Ich habe nur versucht, es für alle klar zu machen. Danke für deinen Code.

12 Stimmen

@Thomas Vervest - Es gibt ein großes Problem mit diesem Code. ^ hebt nicht 2 auf eine Potenz, sondern multipliziert 2 mit dem Ergebnis. Sie wollen Math.pow(2.0, ...). Ansonsten sieht das gut aus.

7 Stimmen

Oh, das ist ein sehr guter Witz! Mein Fehler, ich werde es sofort korrigieren, danke für die Antwort!

238voto

Ephraim Punkte 2224

Ich habe Erfahrung mit iOS und war frustriert, als ich ein Problem mit etwas so Einfachem wie dem Laden und Anzeigen eines Bildes entdeckte. Schließlich versucht jeder, der dieses Problem hat, Bilder in vernünftiger Größe anzuzeigen. Wie auch immer, hier sind die beiden Änderungen, die mein Problem behoben (und meine App sehr reaktionsschnell gemacht).

1) Jedes Mal, wenn Sie BitmapFactory.decodeXYZ() müssen Sie eine BitmapFactory.Options をもって inPurgeable eingestellt auf true (und vorzugsweise mit inInputShareable ebenfalls eingestellt auf true ).

2) NIEMALS verwenden Bitmap.createBitmap(width, height, Config.ARGB_8888) . Ich meine NIEMALS! Ich hatte noch nie, dass das Ding nicht nach ein paar Durchläufen einen Speicherfehler anzeigt. Keine Menge von recycle() , System.gc() was auch immer geholfen hat. Es löste immer eine Ausnahme aus. Die einzige andere Möglichkeit, die tatsächlich funktioniert, ist ein Dummy-Bild in Ihren Drawables (oder ein anderes Bitmap, das Sie mit Schritt 1 oben dekodiert haben), skalieren, dass zu was auch immer Sie wollen, dann manipulieren die resultierende Bitmap (z. B. Weitergabe an ein Canvas für mehr Spaß). Also, was Sie stattdessen verwenden sollten, ist: Bitmap.createScaledBitmap(srcBitmap, width, height, false) . Wenn Sie aus irgendeinem Grund die Brute-Force-Erstellungsmethode verwenden MÜSSEN, dann übergeben Sie zumindest Config.ARGB_4444 .

Damit sparen Sie garantiert Stunden, wenn nicht sogar Tage. Das ganze Gerede über die Skalierung des Bildes usw. funktioniert nicht wirklich (es sei denn, Sie betrachten eine falsche Größe oder ein verschlechtertes Bild als Lösung).

23 Stimmen

BitmapFactory.Options options = new BitmapFactory.Options(); options.inPurgeable = true; y Bitmap.createScaledBitmap(srcBitmap, width, height, false); hat mein Problem mit der Ausnahmeregelung bei Speichermangel unter Android 4.0.0 gelöst. Danke, Kumpel!

6 Stimmen

Beim Aufruf von Bitmap.createScaledBitmap() sollten Sie wahrscheinlich true als Flag-Parameter verwenden. Andernfalls wird die Qualität des Bildes beim Hochskalieren nicht gleichmäßig sein. Lesen Sie diesen Thread stackoverflow.com/questions/2895065/

12 Stimmen

Das ist wirklich ein fabelhafter Ratschlag. Ich wünschte, ich könnte Ihnen ein zusätzliches +1 dafür geben, dass Sie Google für diesen erstaunlich kleinen Fehler zur Rechenschaft gezogen haben. Ich meine... wenn es kein Bug ist, dann muss die Dokumentation wirklich ein paar ernsthaft blinkende Neonschilder haben, die sagen "DIES IST WIE SIE FOTOS VERARBEITEN", weil ich seit 2 Jahren mit diesem Problem kämpfe und erst jetzt diesen Beitrag gefunden habe. Großer Fund.

98voto

Anto Binish Kaspar Punkte 1232

Es ist ein bekannter Fehler ist es nicht wegen der großen Dateien. Da Android die Drawables zwischenspeichert, geht der Speicher nach der Verwendung einiger Bilder zu Ende. Aber ich habe einen alternativen Weg für sie gefunden, durch Überspringen der Android-Standard-Cache-System.

Lösung : Verschieben Sie die Bilder in den Ordner "assets" und verwenden Sie die folgende Funktion, um BitmapDrawable zu erhalten:

public static Drawable getAssetImage(Context context, String filename) throws IOException {
    AssetManager assets = context.getResources().getAssets();
    InputStream buffer = new BufferedInputStream((assets.open("drawable/" + filename + ".png")));
    Bitmap bitmap = BitmapFactory.decodeStream(buffer);
    return new BitmapDrawable(context.getResources(), bitmap);
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X